简体   繁体   English

Java Swing与事件处理

[英]Java Swing with event Handling

I am new in Java Programming and its my first time that i am developing a swing application in java Swing. 我是Java编程的新手,也是我第一次使用Java Swing开发swing应用程序。 i want to implement a simple paint editor that has few buttons to add simple shapes like rectangle,square and etc. The problem is that i cant print the shapes without actionListener but i want to use buttons to do the action for me. 我想实现一个简单的绘画编辑器,该编辑器具有几个按钮来添加简单的形状(如矩形,正方形等)。问题是我无法在没有actionListener的情况下打印形状,但我想使用按钮为我做动作。 I want to print or draw the shape whenever i clicked the button on the same frame that i have the buttons. 我想在有按钮的同一帧上单击按钮时打印或绘制形状。

I have a DrawingPanel.java file which i got it from internet and i wrote these two other classes: 我有一个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);
        }
    }
}

You've got several problems with the code above: 上面的代码有几个问题:

  • Your addRect JPanel's preferred size is 0, 0, and so if and when it is added to the GUI, it will never show. 您的addRect JPanel的首选大小是0、0,因此,如果以及将其添加到GUI时,它将永远不会显示。
  • You add a component to a container (the JFrame's contentPane) during program run, but haven't called revalidate() and repaint() on the container, and so the container's layout managers won't layout the new component. 您在程序运行期间向容器(JFrame的contentPane)中添加了一个组件,但是没有在容器上调用revalidate()repaint() ,因此容器的布局管理器不会对新组件进行布局。
  • You shouldn't swap images by adding JPanels. 您不应该通过添加JPanels来交换图像。 Instead you should have one drawing JPanel, and have it change what it draws by calling public methods on it. 相反,您应该拥有一个绘图JPanel,并通过在其上调用公共方法来更改其绘图。
  • Don't call setVisible(true) on your JFrame until after adding components to it, else some components might not possibly show. 向其添加组件之前不要在JFrame上调用setVisible(true) ,否则某些组件可能无法显示。
  • Avoid setting the size of any Swing component and instead let the components and layout managers size themselves. 避免设置任何Swing组件的大小,而让组件和布局管理器自行调整大小。
  • As an aside, you will want to learn and use Java naming conventions . 顺便说一句,您将要学习和使用Java命名约定 Variable names should all begin with a lower letter while class names with an upper case letter. 变量名都应以小写字母开头,而类名应以大写字母开头。 Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others. 学习并遵循此规则将使我们能够更好地理解您的代码,并使您能够更好地理解其他人的代码。

For example in the code below, I've create several buttons and passed them anonymous ActionListeners, most of them with un-implemented code, and one of them, the listener that calls addRectangle() , with implemented code. 例如,在下面的代码中,我创建了几个按钮,并向它们传递了匿名的ActionListener,其中大多数带有未实现的代码,其中一个是调用了addRectangle()的侦听器,带有已实现的代码。 In the implementation, I simply have the method call a method on the DrawingPanel object: drawingPanel.setDrawRect(true); 在实现中,我只是让方法在DrawingPanel对象上调用一个方法: drawingPanel.setDrawRect(true); . This method changes the state of the drawRect boolean held in the DrawingPanel class, and then calls repaint() on this JPanel. 此方法更改在DrawingPanel类中保存的drawRect布尔型的状态,然后在此JPanel上调用repaint() The JPanel's paintComponent method uses the boolean to decide whether it should draw a rectangle or not: 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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM