【问题标题】:JFrame on OS X with buffer strategy disables rounded corners带有缓冲区策略的 OS X 上的 JFrame 禁用圆角
【发布时间】:2012-08-17 04:59:27
【问题描述】:

我正在尝试在 OS X 中创建一个简单的 JFrame 窗口并在其上渲染一个简单的黑色方块,就像使用 Graphics2d 一样:

public Start() { 
    running = true;
    window = new JFrame("Finest Hour");
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setPreferredSize(new Dimension(500, 500));
    window.setSize(window.getPreferredSize());
    FullScreenUtilities.setWindowCanFullScreen(window, true);
    window.setIgnoreRepaint(true);
    window.setVisible(true);
    window.createBufferStrategy(2);
    strategy = window.getBufferStrategy();
}

public static void main(String[] args) {
    Start s = new Start();
    s.loop();
}

public void loop() {
    Random random = new Random();
    while(running) {
        Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
        g.setColor(Color.black);
        g.fillRect(20, 20, 40, 40);
        strategy.show();
    }
}

但是,当我使用 strategy.show(); 时,窗口底部似乎没有圆角; :

在没有缓冲策略的情况下渲染它,即:Graphics2D = (Graphics2D) window.getGraphics();产生一个圆角的窗口:

我知道这是一个非常小的问题,但它仍然很烦人。有什么办法解决这个问题?

【问题讨论】:

标签: java macos swing graphics graphics2d


【解决方案1】:

对我来说很好。

public class TestMacFrame extends JFrame {

    public TestMacFrame() throws HeadlessException {            
        super("Testing");
        setSize(200, 200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);            
        setLayout(new BorderLayout());
        add(new PaintPane());            
        setVisible(true);
    }

    protected class PaintPane extends JPanel {

        @Override
        protected void paintComponent(Graphics g) {    
            super.paintComponent(g);                
            int width = getWidth() - 1;
            int height = getHeight() - 1;                
            g.setColor(Color.BLACK);                
            int blockWidth = width / 2;
            int blockHeight = height / 2;                
            int x = (width - blockWidth) / 2;
            int y = (height - blockHeight) / 2;                
            g.fillRect(x, y, blockWidth, blockHeight);                
        }            
    }

    public static void main(String[] args) {    
        new TestMacFrame();            
    }
}

现在,我不知道你想做什么,但我可以告诉你:

public void loop() {
    Random random = new Random();
    while(running) {
        Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
        g.setColor(Color.black);
        g.fillRect(20, 20, 40, 40);
        strategy.show();
    }
}

是个坏主意。首先,正如 SoboLAN 指出的那样,您正在尝试更新 Event Dispatching Thread 之外的 UI 组件。 Swing 组件不是Thread 安全的。

其次,这个循环最终会占用您的 CPU 周期,使您的应用程序和整个系统都无法使用。

更新动画

来,试试这个。这是一个非常 BASIC 的例子;)

public class TestMacFrame extends JFrame {

    private float angel = 0;
    private Timer timer;

    public TestMacFrame() throws HeadlessException {
        super("Testing");
        setSize(200, 200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        add(new PaintPane());
        setVisible(true);

        timer = new Timer(25, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                angel += 1;
                repaint();
            }
        });

        timer.setRepeats(true);
        timer.setCoalesce(true);
        timer.setInitialDelay(0);
        timer.start();
    }

    protected class PaintPane extends JPanel {

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g.create();

            int width = getWidth() - 1;
            int height = getHeight() - 1;

            g.setColor(Color.BLACK);

            int blockWidth = width / 2;
            int blockHeight = height / 2;

            int x = (width - blockWidth) / 2;
            int y = (height - blockHeight) / 2;

            g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(angel), width / 2, height / 2));
            g2d.fillRect(x, y, blockWidth, blockHeight);
            g2d.dispose();

        }
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new TestMacFrame();
    }
}

【讨论】:

  • 这个循环是因为我打算使用动画而不是 GUI,因此使用了缓冲区策略和 setIgnoreRepaint();,但 CPU 周期真的那么糟糕吗?我应该如何渲染它?
  • 尝试改用java.swingx.Timer,或者看看其中一个动画框架作品,想到Swing的TimingFramework和Trident
  • @BubbaWoop 我添加了一个非常基本的动画示例
  • 所以我只是尝试了你原来的方法,结果是方角。然而,在调整大小(通过拖动角落)时,我得到了圆角。一定是我的java有问题,是时候更新编辑:我还设法找到了为什么我的原始窗口没有圆角的问题是由于 JFrame.setIgnoreRepaint
  • 编辑 2:我还发现,角落如何变直的真正原因是由于窗口或面板的绘制。如果我强制 repaint() 我再次得到方角。
猜你喜欢
  • 1970-01-01
  • 2010-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多