I have an assignment to create a paint program in Java. I have managed to create something but not exactly what I wanted.
My problem is that I cannot create a JFrame in my IDE(NetBeans 7.0.1) from the options that the IDE gives me, and call the paint classes correctly.
To be more specific I want to press a button from one panel(ex. Panel1) and paint in Panel2,in the same frame.
That's the calling of the class:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
PaintFlower102 f = new PaintFlower102();
}
Part of Class:
super("Drag to Paint");
getContentPane().add(new Label ("Click and Drag"),BorderLayout.SOUTH);
// add(new JButton("Brush 20"),BorderLayout.NORTH);
addMouseMotionListener( new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent event) {
xval=event.getX();
yval=event.getY();
repaint();
}
});
setSize(500, 500);
setVisible(true);
setDefaultCloseOperation(PaintFlower102.DISPOSE_ON_CLOSE);
}
public void paint(Graphics g) {
g.fillOval(xval, yval, 10, 10);
}
The problem is that if I do not put the extend JFrame in the class this doesn't work. And if I do, it creates a new frame in which I can draw.
Suggestions:
Don't ever paint directly in a JFrame except under rare circumstances of absolute need (this isn't one of them).
Instead paint in a JPanel or JComponent or other derivative of JComponent.
Paint in the class's paintComponent(Graphics g) method, not in paint(Graphics g).
Read the Java tutorials on this as it's all explained well there. Check out Trail: 2D Graphics and Performing Custom Painting.
I might be wrong, but I think that you need to include super.paintComponent(g), and override the paintComponent method like Hovercraft Full Of Eels said.
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Draw Oval
g.fillOval(xval, yval, 10, 10);
}
Related
In my application (using java), a button is pushed and then a panel opens up with a graph on it. To create the graph I am using graphics/paint. However, I am unable to get the graphics to show up. For now, I am just trying to paint a circle (instead of the actual graph). It would be much appreciated if someone could explain what I am doing wrong.
public class SeeProgressHandleClass extends JPanel{
public SeeProgressHandleClass(JFrame window) {
this.window = window;
}
public void mouseClicked(MouseEvent e) {
panel = new JPanel();
fillPanel();
window.add(panel);
panel.setBackground(Color.white);
panel.setBounds(50, 40, 1100, 660);
}
public static void fillPanel() {
Graph graph = new Graph();
panel.add(graph);
}
}
public class Graph extends JPanel{
public void paintComponent(Graphics g) {
super.paintComponent(g);
this.setBackground(Color.white);
g.setColor(Color.green);
g.fillOval(50, 50, 50, 50);
}
}
Graph should provide preferredSize hints, which will allow the layout manager to make better determinations about how the component should be displayed. Consider overriding getPreferredSize
Don't call this.setBackground(Color.white); inside paintComponent, each time you do this, it will trigger a potential repaint request, which will eventually consume all your CPU cycles. Set this in the constructor
You're adding Graph into JPanel and then adding this to the screen ... not sure why, but it's making it more confusing
After window.add(panel);, all window.revalidate() and window.repaint() to trigger a new layout and paint pass
I'm working on a project and I just started on the GUI. Since this isn't my most favorite topic, I stumbled real quick on something not working quite right. Everything (PacmanGrid,PacmanScore) is shown correctly but the borders I wrote for the PacmanScore Panel! Anyway here is the code, hope someone can help.
public class PacmanFrame extends JFrame{
public PacmanFrame() {
this.setLayout(new BorderLayout());
this.setTitle("Pacman");
PacmanGrid p1=new PacmanGrid();
PacmanScore p2 = new PacmanScore();
this.add(p1,BorderLayout.CENTER);
this.add(p2,BorderLayout.EAST);
super.setDefaultCloseOperation(EXIT_ON_CLOSE);
super.repaint();
pack();
super.setVisible(true);
}
public static void main(String[] args) {
PacmanFrame p1 = new PacmanFrame();
}
}
PacmanScore
public class PacmanScore extends JPanel{
private TitledBorder t3 = BorderFactory.createTitledBorder("Menu");
private Border etched = BorderFactory.createEtchedBorder(Color.WHITE, Color.white);
public PacmanScore() {
setLayout(new FlowLayout());
setPreferredSize(new Dimension(100,800));
setBackground(Color.DARK_GRAY);
t3.setBorder(etched);
setBorder(t3);
setVisible(true);
setOpaque(true);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
super.paintComponent(g2);
g2.setColor(Color.white);
g2.drawString("Score: ", 20, 400);
}
}
PacmanGrid is also extended by a Panel and draws the classical PacmanGrid using predefined patterns. But I don't think it is relevant since the problem is clearly on the PacmanScore Panel. I will post the code if anyone needs tho.
Thanks in Advance!
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
super.paintComponent(g2);
g2.setColor(Color.white);
g2.drawString("Score: ", 20, 400);
}
You didn't override paint() properly because you didn't invoke super.paint() and therefore the border is not painted.
Don't override paint(). Custom painting is done by overriding paintComponent().
Read the section from the Swing tutorial on A Closer Look at the Paint Mechanism for more information.
Why are you even doing custom painting? Just add a JLabel to the panel.
Also, Swing components (except for top level windows) are visible by default so there is no need to make the panel visible.
I watched a tutorial and tried to do same thing, I wrote the codes exactly the same but it shows nothing. I think it is because paintComponent method is not being called, I also tried to print something to console by paintComponent.
Here is my code:
public class Line extends JPanel{
#Override
public void paintComponents(Graphics g){
super.paintComponent(g);
g.setColor(Color.red);
g.drawLine(100, 10, 30, 40);
}
public static void main(String[] args) {
Line l =new Line();
JFrame myFrame = new JFrame("Line");
myFrame.setSize(600, 400);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.add(l);
myFrame.setVisible(true);
}
}
Thank you!
What you want to override is paintComponent, not paintComponents with a s .
paintComponents paints the child components of the current component (well it sort of tells the child components to paint themselves on the Graphics object).
paintComponent paints the component itself, this is the method you want to override to do custom painting for your component.
I'm trying to make a Paint program using java , I have three events in the jPanel to draw my line.
my problem is that when I am drawing the new line , the first one removed (I think the problem in the dragged event!) .. and so on.
Note that while the mouse is dragged the line will be stucked to the mouse
here is my events code:
private void jPanel1MousePressed(java.awt.event.MouseEvent evt) {
g1=(Graphics2D) jPanel1.getGraphics();
p1=jPanel1.getMousePosition();
}
JLayer lpane;
private void jPanel1MouseDragged(java.awt.event.MouseEvent evt) {
if(p1!=null){
lpane = new JLayer();
jPanel1.add(lpane, BorderLayout.CENTER);
lpane.setBounds(0, 0, 328, 257);
g2=(Graphics2D) lpane.getGraphics();
l=new Line(p1.x,p1.y,jPanel1.getMousePosition().x,jPanel1.getMousePosition().y);
l.draw(g2);
//lpane.repaint();
lpane.setVisible(false);
lpane.removeAll();
lpane.disable(); jPanel1.remove(lpane);
}
}
private void jPanel1MouseReleased(java.awt.event.MouseEvent evt) {
if(p1!=null)
{
g1=(Graphics2D) jPanel1.getGraphics();
p2=jPanel1.getMousePosition();
l=new Line(p1.x,p1.y,p2.x,p2.y);
g1.setColor(Color.red);
l.draw(g1);
p1=null;
}
}
Graphics2D g1,g2; Point p1=null,p2=null; Line l;
getGraphics is not how painting should be done in Swing, instead override the panels paintComponent and paint your components state there.
The paintComponent method needs to know what to paint whenever it is called, as it may be called any number of times, many times without your interaction or knowledge.
One approach is to build a List of shapes or Points, which can then be looped through and painted each time paintComponent is called. The benefit of this is you can remove these shapes/points should you wish.
See Pinting in AWT and Swing and Performing Custom Painting for more detals
Also take a look at this example for an idea
The usual way of doing this is to create a (Buffered)Image the size of your Component, fill the background color, and then draw each new line on the Image as well. In your paintComponent method, all you call is g.drawImage(...);
In your panel:
public void paintComponent(Graphics g) {
if (mSizeChanged) {
handleResize();
}
g.drawImage(mImg, 0, 0, null);
}
In your MouseMotionListener:
public void mouseDragged(MouseEvent me) {
Graphics g = mImg.getGraphics();
Point p = me.getPoint();
g.drawLine(mLastPoint.x, mLastPoint.y, p.x, p.y); }
I cannot get this oval to draw on the JFrame.
static JFrame frame = new JFrame("New Frame");
public static void main(String[] args) {
makeframe();
paint(10,10,30,30);
}
//make frame
public static void makeframe(){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel emptyLabel = new JLabel("");
emptyLabel.setPreferredSize(new Dimension(375, 300));
frame.getContentPane().add(emptyLabel , BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
// draw oval
public static void paint(int x,int y,int XSIZE,int YSIZE) {
Graphics g = frame.getGraphics();
g.setColor(Color.red);
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
The frame displays but nothing is drawn in it. What am I doing wrong here?
You have created a static method that does not override the paint method. Now others have already pointed out that you need to override paintComponent etc. But for a quick fix you need to do this:
public class MyFrame extends JFrame {
public MyFrame() {
super("My Frame");
// You can set the content pane of the frame to your custom class.
setContentPane(new DrawPane());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
setVisible(true);
}
// Create a component that you can actually draw on.
class DrawPane extends JPanel {
public void paintComponent(Graphics g) {
g.fillRect(20, 20, 100, 200); // Draw on g here e.g.
}
}
public static void main(String args[]){
new MyFrame();
}
}
However, as someone else pointed out...drawing on a JFrame is very tricky. Better to draw on a JPanel.
Several items come to mind:
Never override paint(), do paintComponent() instead
Why are you drawing on a JFrame directly? Why not extends JComponent (or JPanel) and draw on that instead? it provides more flexibility
What's the purpose of that JLabel? If it sits on top of the JFrame and covers the entire thing then your painting will be hidden behind the label.
The painting code shouldn't rely on the x,y values passed in paint() to determine the drawing routine's start point. paint() is used to paint a section of the component. Draw the oval on the canvas where you want it.
Also, you're not seeing the JLabel because the paint() method is responsible for drawing the component itself as well as child components. Overriding paint() is evil =)
You are overriding the wrong paint() method, you should override the method named paintComponent like this:
#Override
public void paintComponent(Graphics g)
You need to Override an exist paint method that actually up to dates your Frame. In your case you just created your custom new method that is not called by Frame default.
So change your method to this:
public void paint(Graphics g){
}