简体   繁体   中英

paintComponent not painting onto JPanel

I am working on a homework assignment where I am supposed to make a program that allows you to paint custom shapes and lines, and move them around the screen.

Originally I was using public void paint(g) to paint, but the shapes were flickering when I called repaint.

Because of that I switched over to paintComponent(g) . However When I try to paint a shape nothing shows up. I believe this is because it isn't painting on top of the JPanel .

The frame has 3 panels in a 3 row BorderLayout .

[Button JPanel]
[Draw Box JPanel]
[Coordinate Jpanel]

The panel I would like to draw on is the Draw Box panel, naturally.

Here is the code I have currently:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuBar;
import javax.swing.JPanel;

public class Main extends JPanel implements ActionListener, MouseListener, MouseMotionListener {

private String colors[] = { "Black", "Red", "Orange", "Yellow", "Green", "Blue" };
private String shapes[] = { "Ellipse", "Line", "Rectangle" };
private JMenuBar toolBar; // flow layout? OR box layout x-Axis
private JPanel drawBox;
private JPanel coordBox;
private JLabel coords;
private JButton undo = new JButton("Undo");
private JButton clear = new JButton("Clear");
private JComboBox color = new JComboBox(colors);
private JComboBox shape = new JComboBox(shapes);
private JCheckBox fill = new JCheckBox("Filled");

public Main() {
JFrame frame = new JFrame("Paint");
frame.setSize(400, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setLayout(new BorderLayout());

/*
 * SETUP TOOLBAR
 */
toolBar = new JMenuBar();
toolBar.setLayout(new GridLayout(1, 5));
toolBar.add(undo);
toolBar.add(clear);
toolBar.add(color);
toolBar.add(shape);
toolBar.add(fill);

/*
 * ADD ACTION LISTENERS TO BUTTONS
 */
undo.addActionListener(this);
clear.addActionListener(this);
color.addActionListener(this);
shape.addActionListener(this);
fill.addActionListener(this);

/*
 * SETUP DRAW BOX
 */
drawBox = new JPanel();
drawBox.setOpaque(true);
drawBox.setPreferredSize(new Dimension(600, 400));
drawBox.addMouseListener(this);
drawBox.addMouseMotionListener(this);

/*
 * SETUP COORDINATES
 */
coords = new JLabel();
coordBox = new JPanel();

coordBox.setBackground(new Color(211, 211, 211));
coordBox.setPreferredSize(new Dimension(drawBox.getWidth(), 25));

coords.setText("Coords: [0,0]");
coords.addMouseMotionListener(this);

coordBox.add(coords);

/*
 * ADD TO FRAME
 */

frame.add(toolBar, BorderLayout.NORTH);
frame.add(drawBox, BorderLayout.CENTER);
frame.add(coordBox, BorderLayout.SOUTH);

frame.pack();

}

public static void main(String[] args) {
Main m = new Main();
}

public void paintComponent(Graphics g) {
// super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(300, 300, 100, 100);

}

@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == undo) {
    System.out.println("Undo Last");
}

if (e.getSource() == clear) {
    System.out.println("clearing screen");
}
// COLOR DROP DOWN BOX
if (e.getSource() == color) {
    JComboBox cb = (JComboBox) e.getSource();
    String selected = (String) cb.getSelectedItem();
    switch (selected) {

    case "Red":
    System.out.println("switching to color red");
    //ellipse.setColor(Color.RED);

    break;

    case "Orange":
    System.out.println("switch to coor orange");
    //ellipse.setColor(Color.ORANGE);
    break;
    case "Yellow":
    System.out.println("switching to color yellow");
    break;
    case "Green":
    System.out.println("Switching to green");
    //ellipse.setColor(Color.GREEN);

    break;
    case "Blue":
    System.out.println("Switching to blue");
    break;
    default:
    System.out.println("NOthing selected");
    break;
    }
}
// SHAPE DROP DOWN BOX
if (e.getSource() == shape) {
    JComboBox cb = (JComboBox) e.getSource();
    String selected = (String) cb.getSelectedItem();
    switch (selected) {
    case "Ellipse":
    System.out.println("switching to ellipse");
    break;
    case "Line":
    System.out.println("switch to line");
    break;
    case "Rectangle":
    System.out.println("switching to rectangle");
    break;

    default:
    System.out.println("NOthing selected");
    break;
    }
}

if (e.getSource() == fill) {
    JCheckBox cb = (JCheckBox) e.getSource();
    if (cb.isSelected()) {
    System.out.println("Fill shape");
    //ellipse.setFilled(true);
    } else {
    System.out.println("Empty shape");
    //ellipse.setFilled(false);
    }
}

}

@Override
public void mouseClicked(MouseEvent arg0) {
// System.out.println("Mouse clicked");

}

@Override
public void mouseEntered(MouseEvent e) {
System.out.println("Mouse entered");
}

@Override
public void mouseExited(MouseEvent arg0) {
coords.setText("Coords: N/A");

}

@Override
public void mousePressed(MouseEvent arg0) {
System.out.println("Mouse pressed");

}

@Override
public void mouseReleased(MouseEvent arg0) {
System.out.println("Mouse Released");

}

@Override
public void mouseDragged(MouseEvent e) {
coords.setText("Coords: [" + e.getX() + "," + e.getY() + "]");
}

@Override
public void mouseMoved(MouseEvent e) {
coords.setText("Coords: [" + e.getX() + "," + e.getY() + "]");
// repaint();
// revalidate();

}
}

Your Main class extends JPanel, has a paintComponent method -- but you never add an instance of Main to the GUI , instead you add a plain-vanilla JPanel, drawBox to the GUI, and so of course paintComponent will never be called.

Solution: add Main or this to the GUI, not a plain JPanel.

The panel I would like to draw on is the Draw Box JPanel naturally.

drawBox = new JPanel();

Well you didn't override the paintComponent(...) method of your "drawBox" panel so no painting will happen.

Also, whenever you always need to invoke super.paintComponent(...) at the start of your paintComponent(...) method.

Check out Custom Painting Approaches for working examples of the two common ways to do custom painting.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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