Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Java Graphics paint()
New Posts  All Forums:Forum Nav:

Java Graphics paint()

post #1 of 8
Thread Starter 
So I'm working on a board game in Java and I need to have a marker move around the board (an iconified JLabel). I'm using a JLayerdPane and I can get the movement just fine, and I get the shape drawn. The problem I'm having is that the graphics don't update. They just draw new markers. So after 5 moves, there are 5 markers on the board. I don't want to use something like g.dispose() and then keep creating new Graphics objects, but I'm not sure of another way to go about it.

I was thinking of using g.translate(), but to my knowledge, Graphics references are deleted as soon as they're used. Anyone know of an update, or a way I can override repaint() to simply move the current graphic to a new location?

This is what I've managed to do. Which works, but it's not very clean.
Code:

    public void paint(java.awt.Graphics g){
        java.awt.Graphics Gr = this.getGraphics();
        if(Gr != null)
            Gr.dispose();
        g.setColor(new java.awt.Color(125,0,125));
        g.fillOval(x,y,20,20);
    }
    
    public void setCoord(int xloc, int yloc){
        x = xloc;
        y = yloc;
        repaint();
    }
RAID0R
(14 items)
 
  
CPUMotherboardGraphicsRAM
i5 750 4.0GHz MSI P55-GD80 GTX 470 | 8800GT PhysX 2x2GB G.Skill Ripjaws 
Hard DriveOptical DriveCoolingOS
60GB Agility 2|1TB RAID0|1.5TB Pioneer DVR-217D XSPC Raystorm | XSPC RX240 Windows 7 Professional x64 
MonitorKeyboardPowerCase
27" Dell 2709W | 17" Samsung Logitech G15 Corsair HX850 Corsair 650D 
Mouse
Microsoft IntelliMouse 
  hide details  
Reply
RAID0R
(14 items)
 
  
CPUMotherboardGraphicsRAM
i5 750 4.0GHz MSI P55-GD80 GTX 470 | 8800GT PhysX 2x2GB G.Skill Ripjaws 
Hard DriveOptical DriveCoolingOS
60GB Agility 2|1TB RAID0|1.5TB Pioneer DVR-217D XSPC Raystorm | XSPC RX240 Windows 7 Professional x64 
MonitorKeyboardPowerCase
27" Dell 2709W | 17" Samsung Logitech G15 Corsair HX850 Corsair 650D 
Mouse
Microsoft IntelliMouse 
  hide details  
Reply
post #2 of 8
Stick a double buffer in there. It will eliminate flickering and probably solve your issue. TBH it seems as if it isn't clearing the screen - just drawing more stuff on top of what you have
It goes to eleven
(13 items)
 
  
CPUMotherboardGraphicsRAM
E6300 DS3 EVGA 8600GTS 2GB XMS2 DDR2-800 
Hard DriveOSMonitorKeyboard
1.294 TB Arch Linux/XP Samsung 226bw Eclipse II 
PowerCaseMouse
Corsair 520HX Lian-Li v1000B Plus G7 
  hide details  
Reply
It goes to eleven
(13 items)
 
  
CPUMotherboardGraphicsRAM
E6300 DS3 EVGA 8600GTS 2GB XMS2 DDR2-800 
Hard DriveOSMonitorKeyboard
1.294 TB Arch Linux/XP Samsung 226bw Eclipse II 
PowerCaseMouse
Corsair 520HX Lian-Li v1000B Plus G7 
  hide details  
Reply
post #3 of 8
Thread Starter 
Quote:
Originally Posted by rabidgnome229 View Post
Stick a double buffer in there. It will eliminate flickering and probably solve your issue. TBH it seems as if it isn't clearing the screen - just drawing more stuff on top of what you have
It's clearing fine and working without flickering, but it's doing so very inefficiently. It's creating a new Graphics object every time the shape redraws. It disposes the original graphic and creates a new one rather than just updating the old one.

This part erases the previous image:

Code:
java.awt.Graphics Gr = this.getGraphics();
        if(Gr != null)
            Gr.dispose();
And this part draws the new location:

Code:
g.setColor(new java.awt.Color(125,0,125));
        g.fillOval(x,y,20,20);
Ideally I would somehow give the existing drawn shape a new coordinate and just repaint it. It's seems, however, that once a shape is drawn all references relating to it are eliminated. Forcing you do dispose all current graphics and draw new ones. Other than getGraphics(), I haven't found a way to gain access to the original drawn shape.
RAID0R
(14 items)
 
  
CPUMotherboardGraphicsRAM
i5 750 4.0GHz MSI P55-GD80 GTX 470 | 8800GT PhysX 2x2GB G.Skill Ripjaws 
Hard DriveOptical DriveCoolingOS
60GB Agility 2|1TB RAID0|1.5TB Pioneer DVR-217D XSPC Raystorm | XSPC RX240 Windows 7 Professional x64 
MonitorKeyboardPowerCase
27" Dell 2709W | 17" Samsung Logitech G15 Corsair HX850 Corsair 650D 
Mouse
Microsoft IntelliMouse 
  hide details  
Reply
RAID0R
(14 items)
 
  
CPUMotherboardGraphicsRAM
i5 750 4.0GHz MSI P55-GD80 GTX 470 | 8800GT PhysX 2x2GB G.Skill Ripjaws 
Hard DriveOptical DriveCoolingOS
60GB Agility 2|1TB RAID0|1.5TB Pioneer DVR-217D XSPC Raystorm | XSPC RX240 Windows 7 Professional x64 
MonitorKeyboardPowerCase
27" Dell 2709W | 17" Samsung Logitech G15 Corsair HX850 Corsair 650D 
Mouse
Microsoft IntelliMouse 
  hide details  
Reply
post #4 of 8
Test out dispose and make sure its doing what its supposed to be doing. Dispose and immediately repaint to see what you get.
It goes to eleven
(13 items)
 
  
CPUMotherboardGraphicsRAM
E6300 DS3 EVGA 8600GTS 2GB XMS2 DDR2-800 
Hard DriveOSMonitorKeyboard
1.294 TB Arch Linux/XP Samsung 226bw Eclipse II 
PowerCaseMouse
Corsair 520HX Lian-Li v1000B Plus G7 
  hide details  
Reply
It goes to eleven
(13 items)
 
  
CPUMotherboardGraphicsRAM
E6300 DS3 EVGA 8600GTS 2GB XMS2 DDR2-800 
Hard DriveOSMonitorKeyboard
1.294 TB Arch Linux/XP Samsung 226bw Eclipse II 
PowerCaseMouse
Corsair 520HX Lian-Li v1000B Plus G7 
  hide details  
Reply
post #5 of 8
Thread Starter 
I should probably clarify. The methods that I have posted do EXACTLY what I want them to do. Here is my concern. Since, in my experience, the garbage collection in Java is rather crappy, it has always been my programming practice to create as few new objects as I can, and just update existing ones with any changes that occur. In other words, say you're going to have a window pop up 1000 times in the duration of a program. Rather than going

Code:
 public void update(String msg){
output = new JFrame(msg);
// the previous output no longer has a reference so it's garbage collected whenever.
}
With that method, you just keep creating new objects in order to see the new information. That's how my painting method works right now. It releases all the graphics references and paints new ones. Instead, I'd like something like this:

Code:
 public void update(String msg){
 output.setTitle(msg);
// the same object is used the whole time, so you don't get a bunch of new
// objects waiting to get collected.
 }
I was hoping to be able to use the same graphics object the entire time, and just shift it's position, much like you'd use a set method to update an objects properties rather than create a whole new object with the desired properties. I wouldn't be so worried, but I had to do a major re-write on a couple methods because I just kept creating new objects rather than modifying existing ones, and the garbage collection couldn't keep out and I ran into heap overflows.
RAID0R
(14 items)
 
  
CPUMotherboardGraphicsRAM
i5 750 4.0GHz MSI P55-GD80 GTX 470 | 8800GT PhysX 2x2GB G.Skill Ripjaws 
Hard DriveOptical DriveCoolingOS
60GB Agility 2|1TB RAID0|1.5TB Pioneer DVR-217D XSPC Raystorm | XSPC RX240 Windows 7 Professional x64 
MonitorKeyboardPowerCase
27" Dell 2709W | 17" Samsung Logitech G15 Corsair HX850 Corsair 650D 
Mouse
Microsoft IntelliMouse 
  hide details  
Reply
RAID0R
(14 items)
 
  
CPUMotherboardGraphicsRAM
i5 750 4.0GHz MSI P55-GD80 GTX 470 | 8800GT PhysX 2x2GB G.Skill Ripjaws 
Hard DriveOptical DriveCoolingOS
60GB Agility 2|1TB RAID0|1.5TB Pioneer DVR-217D XSPC Raystorm | XSPC RX240 Windows 7 Professional x64 
MonitorKeyboardPowerCase
27" Dell 2709W | 17" Samsung Logitech G15 Corsair HX850 Corsair 650D 
Mouse
Microsoft IntelliMouse 
  hide details  
Reply
post #6 of 8
Why do you have two different graphics objects? this.getGraphics() may be doing a deep copy. I somehow doubt this is the case - but it is a worrying portion of code.
It goes to eleven
(13 items)
 
  
CPUMotherboardGraphicsRAM
E6300 DS3 EVGA 8600GTS 2GB XMS2 DDR2-800 
Hard DriveOSMonitorKeyboard
1.294 TB Arch Linux/XP Samsung 226bw Eclipse II 
PowerCaseMouse
Corsair 520HX Lian-Li v1000B Plus G7 
  hide details  
Reply
It goes to eleven
(13 items)
 
  
CPUMotherboardGraphicsRAM
E6300 DS3 EVGA 8600GTS 2GB XMS2 DDR2-800 
Hard DriveOSMonitorKeyboard
1.294 TB Arch Linux/XP Samsung 226bw Eclipse II 
PowerCaseMouse
Corsair 520HX Lian-Li v1000B Plus G7 
  hide details  
Reply
post #7 of 8
Thread Starter 
Quote:
Originally Posted by rabidgnome229 View Post
Why do you have two different graphics objects? this.getGraphics() may be doing a deep copy. I somehow doubt this is the case - but it is a worrying portion of code.
The reason for 2 graphics objects is as follows:

On the original painting of the graphics object g, as soon as the paint method finishes, it's to my understanding from a few sources that all references to that graphics object g are severed. The only way to gain access back to that original drawn shape (as far as I know) is to use this.getGraphics(); in order to have some reference to that original drawn shape. I MUST get access to that original g in order to dispose/erase it, since I only want one movement marker to be visible per player.

As I mentioned, this functionally works perfectly, but it's not an ideal approach. If you know of some way to gain access to the original graphics object so it can be erased/updated, without calling getGraphics(), it would be incredibly helpful. I've played a few games through completely with no problems with whatsoever, so it may not be a huge concern.
RAID0R
(14 items)
 
  
CPUMotherboardGraphicsRAM
i5 750 4.0GHz MSI P55-GD80 GTX 470 | 8800GT PhysX 2x2GB G.Skill Ripjaws 
Hard DriveOptical DriveCoolingOS
60GB Agility 2|1TB RAID0|1.5TB Pioneer DVR-217D XSPC Raystorm | XSPC RX240 Windows 7 Professional x64 
MonitorKeyboardPowerCase
27" Dell 2709W | 17" Samsung Logitech G15 Corsair HX850 Corsair 650D 
Mouse
Microsoft IntelliMouse 
  hide details  
Reply
RAID0R
(14 items)
 
  
CPUMotherboardGraphicsRAM
i5 750 4.0GHz MSI P55-GD80 GTX 470 | 8800GT PhysX 2x2GB G.Skill Ripjaws 
Hard DriveOptical DriveCoolingOS
60GB Agility 2|1TB RAID0|1.5TB Pioneer DVR-217D XSPC Raystorm | XSPC RX240 Windows 7 Professional x64 
MonitorKeyboardPowerCase
27" Dell 2709W | 17" Samsung Logitech G15 Corsair HX850 Corsair 650D 
Mouse
Microsoft IntelliMouse 
  hide details  
Reply
post #8 of 8
say the background (whatever's behind the 'marker' that is being moved) is black. modify your paint() method assuming this is true:

void paint(Graphics g)
{
g.setColor(java.awt.Color.BLACK);
g.fillOval(x,y,20,20);
g.setColor(new java.awt.Color(125,0,125));
g.fillOval(newX,newY,20,20);
x = newX;
y= newY;
}

public void setCoord(int xloc, int yloc)
{
newX = xloc;
newY = yloc;
repaint();
}

if you wanted to use multiple markers, just do a foreach loop int the paint method for every marker in an array of markers. in this case, you should probably have the x, y, newX, and newY variables be state variables local to a Marker object...but this should work for now pm me if you want; my subscriptions are full.
citrinitas
(14 items)
 
  
CPUMotherboardGraphicsRAM
QX9650 DFI LanParty DK P35-T2RS eVGA GTX260 SSC 4 x 1GB DDR2 Ballistix 1066MHz Dual Channel -D9MGH 
Hard DriveHard DriveOptical DriveOS
3 x 7200.11 500GB RAID 5 32GB Corsair V32 SSD (OS) none, and proud of it. ODD = obsolete tech! Win 7 
MonitorPowerCaseMouse
Acer X241W 24" WS TT Toughpower 700W Rocketfish + mods Logitech G9 
  hide details  
Reply
citrinitas
(14 items)
 
  
CPUMotherboardGraphicsRAM
QX9650 DFI LanParty DK P35-T2RS eVGA GTX260 SSC 4 x 1GB DDR2 Ballistix 1066MHz Dual Channel -D9MGH 
Hard DriveHard DriveOptical DriveOS
3 x 7200.11 500GB RAID 5 32GB Corsair V32 SSD (OS) none, and proud of it. ODD = obsolete tech! Win 7 
MonitorPowerCaseMouse
Acer X241W 24" WS TT Toughpower 700W Rocketfish + mods Logitech G9 
  hide details  
Reply
New Posts  All Forums:Forum Nav:
  Return Home
  Back to Forum: Coding and Programming
Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Java Graphics paint()