paintComponent Java的问题 - Swing

时间:2016-04-09 22:28:51

标签: java swing paintcomponent

我试图编码一个摆动gui,我可以通过按两个不同的JMenuItems,圆形和一个矩形在随机位置绘制形状。 我得到了它的工作,但我用

Graphics2D gg = (Graphics2D) canvas.getGraphics();

我被建议使用和覆盖paintComponent()。所以我几个小时前就开始尝试了:D 我知道有很多关于这方面的问题,但我真的读过很多,经过尝试和搜索,但我无法帮助自己......

请查看我的RandomDrawer类,我发现我必须在那里实现paintComponent()(我希望至少这样)。 进一步在下一个方法

public void actionPerformed(ActionEvent e)

即时通讯我知道哪个动作发生了,我可以或者我怎么能告诉他事后画画?或者我的整个方法是否有缺陷?

这是我的代码。

感谢您对我的感谢和非常感谢。

package plotterpackage;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.util.Random;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;
import javax.swing.text.JTextComponent;



public class PlotterApp implements ComponentListener  {
private JFrame frame;
private JPanel canvas;
private JPanel statusBar;
private JTextField status;
/**
 * Public default constructor.    
 */
public PlotterApp() {
    initialize();
}
/**
 * Start of the application.
 * @param args command line arguments
 */
public static void main(String[] args) {
    PlotterApp app = new PlotterApp();
    app.start();
}
/**
 * Initialize the application.
 */
protected void initialize() {
    frame = new JFrame("Main");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setBounds(50,50, 50+640, 50+480);
    frame.setBackground(Color.GREEN);
    frame.setJMenuBar(createMenuBar());

    frame.getContentPane().add(createContent(), BorderLayout.CENTER);
    frame.getContentPane().add(createStatusBar(),BorderLayout.SOUTH);        
}
/**
 * Start the graphical user interface.
 */
public void start() {
    // show the GUI
    frame.setVisible(true);
    status.setText("Application started");
}
/**-*
 * Internal helper to create the main content.
 * @return component with application content.
 */
protected JComponent createContent() {
    canvas = new JPanel();
    canvas.addMouseListener(new Painter());
    canvas.addMouseMotionListener(new Painter());
    canvas.addComponentListener(this);
    canvas.setBackground(new Color(128,218,255));
    canvas.setForeground(Color.RED);
    canvas.setBorder(new BevelBorder(BevelBorder.LOWERED));
    return canvas;
}
/**
 * Internal helper to create the statusbar and -fields.
 * @return component with status/bar.
 */    
protected JComponent createStatusBar() {
    FlowLayout layout = new FlowLayout(FlowLayout.LEFT);
    layout.setHgap(5);

    statusBar = new JPanel(layout);
    statusBar.add(new JLabel("Status: "));

    status = new JTextField();
    status.setPreferredSize(new Dimension(400,25));
    status.setEditable(false);
status.setBorder(newBevelBorder(BevelBorder.RAISED,Color.MAGENTA,Color.LIGHT_GRAY));
    status.getInsets().set(2, 10, 2, 10);
    statusBar.add(status);

    return statusBar;
}
/**
 * Internal helper to create the frames menubar.
 * @return menu bar 
 */
protected JMenuBar createMenuBar() {
    JMenuBar mb = new JMenuBar();
    JMenuItem item;
    JMenu menu;
    // Action menu
    menu = new JMenu("Actions");
    mb.add(menu);
    item = new JMenuItem("Draw RandomCircle");
    item.addActionListener(new RandomDrawer());
    menu.add(item);

    item = new JMenuItem("Draw RandomRectangle");
    item.addActionListener(new RandomDrawer());
    menu.add(item);

    menu.addSeparator();
    item = new JMenuItem("Exit");
    item.addActionListener(new AppCloser());
    menu.add(item);

    // Color menu not used so far
    menu = new JMenu("Colors");        
    mb.add(menu);
    // Help menu not used so far
    menu = new JMenu("Help");        
    mb.add(menu);

    return mb;
}

class AppCloser implements ActionListener {
    /* (non-Javadoc)
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("application finished, bye-bye... ");
        frame.setVisible(false);
        frame.dispose();
        System.exit(0);
    }        
}

class RandomDrawer extends JPanel implements ActionListener {
    /* (non-Javadoc)
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */ 
    @Override
    protected void paintComponent(Graphics g) {
          super.paintComponent(g);
          Graphics2D g2 = (Graphics2D) g;
          g2.setColor(Color.BLACK);
          g2.drawOval(100, 100, 100, 100);  
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Random generator = new Random();
        int x = generator.nextInt(100)+100;
        int y = generator.nextInt(100)+100;
        int w;

        if (e.getActionCommand()==("Draw RandomCircle")) {
            System.out.printf("x = %d y = %d\n", x, y);
            //status.setText(String.format("rnd draw x:  y: "));
            //gg.setColor(Color.BLACK);
            //gg.drawOval(x, y, generator.nextInt(x), generator.nextInt(y));    
        }

        else if (e.getActionCommand()==("Draw RandomRectangle")) {
            System.out.printf("x = %d y = %d\n", x, y);
            //status.setText(String.format("rnd draw x:  y: "));
            //Graphics2D gg = (Graphics2D) canvas.getGraphics();
            //gg.setColor(Color.BLACK);
            //gg.drawRect(x, y, generator.nextInt(x), generator.nextInt(y));    
        }
    }
}


class Painter extends MouseAdapter implements MouseMotionListener {

  Point start, end;
  int startX, startY, oldX, oldY, oldWidth, oldHeight;

  public void mousePressed(MouseEvent e) {
    start = e.getPoint();
    oldX = startX;
    oldY = startY;
    startX = e.getX();
    startY = e.getY();
    status.setText(String.format("Mouse start: " + start));
  }

  public void mouseDragged(MouseEvent e) {
    Graphics2D gc = (Graphics2D)canvas.getGraphics();
    gc.setColor(new Color(128, 218, 255));
    gc.drawOval(oldX, oldY, oldWidth, oldHeight);
    System.out.printf("oldWidth ist = %3d, oldHeight ist = %3d\n", oldWidth, oldHeight);
    oldWidth = e.getX();
    oldHeight = e.getY();
    gc.setColor(Color.BLACK);
    gc.drawOval(startX, startY, e.getX(), e.getY());
  }

  public void mouseReleased(MouseEvent e) {
    end = e.getPoint();
    status.setText(String.format("Mouse end: " + end));
  }
}


@Override
public void componentHidden(ComponentEvent e) {
    // TODO Auto-generated method stub

}
@Override
public void componentMoved(ComponentEvent e) {
    // TODO Auto-generated method stub

}
@Override
public void componentResized(ComponentEvent e) {
    // TODO Auto-generated method stub

}
@Override
public void componentShown(ComponentEvent e) {
    // TODO Auto-generated method stub

}
}

2 个答案:

答案 0 :(得分:1)

您可以将形状放置在某种容器中,如ArrayList。 在 paintComponent(Graphics g)中,您应该从该列表中绘制每个形状,并在 actionPerformed(ActionEvent e)内部,您应该使用 repaint()方法你绘制的一个物体。

答案 1 :(得分:1)

不要......

Graphics2D gg = (Graphics2D) canvas.getGraphics();

这不是应该如何进行自定义绘画。 Swing会询问你什么时候需要绘画,并且你需要重新绘制组件的当前状态。

首先查看Painting in AWT and SwingPerforming Custom Painting了解更多详情

基本上,您需要覆盖paintComponent的{​​{1}}方法(确保首先调用JPanel)并绘制组件的当前状态。

您需要以对您最有用的任何形式存储状态(super.paintComponent或自定义对象,甚至是List

您可以在更改状态时通过调用Image来请求API更新用户界面