Java Swing与事件处理

时间:2016-07-09 19:06:30

标签: java swing paintcomponent

我是Java编程的新手,也是我第一次在Java Swing中开发swing应用程序。 我想实现一个简单的油漆编辑器,它只有很少的按钮来添加简单的形状,如矩形,方形等。 问题是我不能在没有actionListener的情况下打印形状,但我想使用按钮为我做动作。 每当我点击同一个框架上的按钮时,我想要打印或绘制形状。

我有一个DrawingPanel.java文件,我是从互联网上获得的,我写了另外两个类:

import java.awt.*;
import javax.swing.*;

public class addRect extends JPanel {
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.fillRect(50, 30, 200, 100);
        g.setColor(Color.BLUE);

    }
}

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;` 

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

        public JFrame frame;
        private JButton button1;
        private JButton button2;
        private JButton button3;
        private JButton button4;

    public test() {

        frame = new JFrame("Paint Program");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(new Dimension(350, 100));
        button1=new JButton("AddRectangle");
        button2=new JButton("AddSquare");
        button3=new JButton("AddCircle");
        button4=new JButton("Clear");

        frame.setVisible(true);
        button1.addActionListener(new VerifyListener());


        frame.setLayout(new FlowLayout());
        frame.add(button1);
        frame.add(button2);
        frame.add(button3);
        frame.add(button4);
    }
    public class VerifyListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            addRect panel=new addRect();
            frame.add(panel);
            panel.setVisible(true);
        }
    }
}

1 个答案:

答案 0 :(得分:3)

上面的代码有几个问题:

  • 你的addRect JPanel的首选大小是0,0,所以如果它被添加到GUI,它将永远不会显示。
  • 您在程序运行期间向容器添加了一个组件(JFrame的contentPane),但是没有在容器上调用revalidate()repaint(),因此容器的布局管理器不会布局新组件。
  • 您不应通过添加JPanel来交换图像。相反,你应该有一个绘图JPanel,并通过调用它上面的公共方法来改变它绘制的内容。
  • 不要在JFrame上调用setVisible(true),直到 为其添加组件后,否则可能无法显示某些组件。
  • 避免设置任何Swing组件的大小,而是让组件和布局管理器自行调整大小。
  • 另外,您需要学习并使用Java naming conventions。变量名都应以较低的字母开头,而类名以大写字母开头。了解并遵循这一点将使我们能够更好地理解您的代码,并使您能够更好地理解其他代码。

例如,在下面的代码中,我创建了几个按钮并向它们传递了匿名的ActionListeners,其中大多数都是未实现的代码,其中一个是调用addRectangle()的侦听器,带有实现的代码。在实现中,我只是让方法在DrawingPanel对象上调用一个方法:drawingPanel.setDrawRect(true);。此方法更改DrawingPanel类中保存的drawRect boolean的状态,然后在此JPanel上调用repaint()。 JPanel的paintComponent方法使用布尔值来决定是否应该绘制矩形:

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

public class TestDrawingPanel extends JPanel {
    private JButton addRectButton = new JButton("Add Rectangle");
    private JButton addSquareButton = new JButton("Add Square");
    private JButton addCircleButton = new JButton("Add Circle");
    private JButton clearButton = new JButton("Clear");

    private DrawingPanel drawingPanel = new DrawingPanel();

    public TestDrawingPanel() {
        // add ActionListeners
        addRectButton.addActionListener(evt -> addRectangle());
        addSquareButton.addActionListener(evt -> addSquare());
        addCircleButton.addActionListener(evt -> addCircle());
        clearButton.addActionListener(evt -> clear());
        JButton[] btns = { addRectButton, addSquareButton, addCircleButton, clearButton };

        // jpanel uses grid layout with one row and variable number of columns
        // and add all buttons to it
        JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 3, 3));
        for (JButton btn : btns) {
            buttonPanel.add(btn);
        }

        setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); // blank border
        setLayout(new BorderLayout());
        add(buttonPanel, BorderLayout.PAGE_START); // add button panel to the top
        add(drawingPanel, BorderLayout.CENTER);  // add drawing panel to the center
    }

    private void addRectangle() {
        drawingPanel.setDrawRect(true);  // tell the drawing panel to draw the rectangle
    }

    private void addSquare() {
        // TODO: implement        
    }

    private void addCircle() {
        // TODO: implement
    }

    private void clear() {
        drawingPanel.setDrawRect(false);
        // TODO: complete
    }

    private static void createAndShowGui() {
        TestDrawingPanel mainPanel = new TestDrawingPanel();

        JFrame frame = new JFrame("Paint Program");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

}

// class addRect extends JPanel {
class DrawingPanel extends JPanel {
    // size information
    private static final int PREF_W = 300;
    private static final int PREF_H = PREF_W;
    private boolean drawRect = false;  // use this to decide if should draw rectangle or not

    public DrawingPanel() {
        setBorder(BorderFactory.createTitledBorder("Drawing Panel"));
    }

    // allow outside classes to set the drawRect field
    public void setDrawRect(boolean drawRect) {
        this.drawRect = drawRect;
        repaint();
    }

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

        // if true, draw the rectang.e
        if (drawRect) {
            g.setColor(Color.BLUE);
            g.fillRect(50, 30, 200, 100);
        }

        // TODO: complete rest
    }

    // So that the drawing JPanel will size appropriately
    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }
}