Java Swing Repaint 缓慢或无法工作

标签 java swing graphics jpanel paintcomponent

我正在尝试使用 boolean 标志基于按钮单击来绘制图形。之前,我在 ShapeGUI 类中将 boolean 值设置为公共(public)静态 boolean 类型,并使用 Shape.draw 在 ShapeListener 中调用它,这很有效,尽管需要大约 10 秒才能生成绘图。

现在我在 ShapeListener 类本身内部设置了 boolean 标志。现在它要么不重新绘制,要么速度非常慢。如何在单击按钮时立即显示绘图?

public class ShapeGUI extends JFrame
{
    public static final int WIDTH = 500;
    public static final int HEIGHT = 500;

    public ShapeGUI()
    {
        setSize(WIDTH, HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //setLayout(new FlowLayout());
        setLocationRelativeTo(null);
        JMenuBar menu = new JMenuBar();
        JMenu file = new JMenu("File");
        menu.add(file);
        JMenuItem save = new JMenuItem("Save Information");
        JMenuItem exit = new JMenuItem("Exit");
        file.add(save);
        file.add(exit);               
        setJMenuBar(menu);

        ShapeListener test = new ShapeListener();        
        JButton button = new JButton("Hello"); 
        test.setBackground(Color.CYAN);
        button.addActionListener(new ShapeListener());
        test.add(button); 
        add(test);

//followed this person's advice        
//First off, your drawing should be done in a paintComponent method override that is held in a class that extends JPanel. Next, this class could have a boolean variable that the paintComponent uses to decide if it will draw a rectangle or not. The button press simply sets the boolean variable and calls repaint on the drawing JPanel.
    }
}

    public class ShapeListener extends JPanel implements ActionListener

    {

    boolean draw = false;
    Shape s = new Circle();
    Shape a = new Rectangle();

    @Override
    public void actionPerformed(ActionEvent e) 
    {
        draw = true;
        repaint();
    }
    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        if(draw)
        {
        s.draw(g);
        }
        else
        {
            a.draw(g);
        }

    }

}

最佳答案

你的逻辑有点不对劲……

ShapeListener test = new ShapeListener(); // First instance
JButton button = new JButton("Hello");
test.setBackground(Color.CYAN);
button.addActionListener(new ShapeListener()); // Second instance...
test.add(button);
add(test);

您创建 ShapeListener 类的两个实例,将一个添加到容器中,并将另一个用作操作监听器。两者都不会互相了解,这意味着您可以单击“奶牛回家”,ShapeListener 的第一个实例永远不会改变。

此外,除非您打算重写 ShapeListener Pane 的 preferredSize 方法,否则我会在框架,以确保面板正确布局,否则看起来面板没有被绘制...

尝试类似...

public class ShapeGUI extends JFrame {

    public static final int WIDTH = 500;
    public static final int HEIGHT = 500;

    public ShapeGUI() {
        setSize(WIDTH, HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        JMenuBar menu = new JMenuBar();
        JMenu file = new JMenu("File");
        menu.add(file);
        JMenuItem save = new JMenuItem("Save Information");
        JMenuItem exit = new JMenuItem("Exit");
        file.add(save);
        file.add(exit);
        setJMenuBar(menu);

        setLayout(new BorderLayout());

        ShapeListener test = new ShapeListener();
        JButton button = new JButton("Hello");
        test.setBackground(Color.CYAN);
        button.addActionListener(test);
        test.add(button);
        add(test);

        setVisible(true);

    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                new ShapeGUI();

            }
        });
    }

    public class ShapeListener extends JPanel implements ActionListener {

        Shape s = new Ellipse2D.Float(0, 0, 20, 20);
        Shape a = new Rectangle2D.Float(0, 0, 20, 20);

        private Shape paintMe = a;

        @Override
        public void actionPerformed(ActionEvent e) {
            paintMe = s;
            repaint();
        }

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

            int x = (getWidth() - paintMe.getBounds().width) / 2;
            int y = (getHeight() - paintMe.getBounds().height) / 2;

            Graphics2D g2d = (Graphics2D) g.create();
            g2d.translate(x, y);
            g2d.draw(paintMe);
            g2d.dispose();

        }
    }
}

相反...

关于Java Swing Repaint 缓慢或无法工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12773418/

相关文章:

java - 如何强制终止数据源并重新加载连接池?

python - 只用python制作的简单游戏

r - 并排绘制 2 个 tmap 对象

java - JPanels 无法设置任何大小值

java - 如何在 ChartPanel 顶部绘制图形?

java - Spring:如何在 Spring 配置中注入(inject) ENUM?

java.lang.ClassNotFoundException : org. owasp.csrfguard.CsrfGuardHttpSessionListener?

java - 来自 JTextArea Java 的 ActionListener

java - 您将要为 Java 应用程序中的按钮加载的图像放在哪里?

java - JAVA求线段长度