how to repaint all JTabbedPane panels [duplicate] - java

I have a jPanel, which contains a number of sub-panels that can be dragged around. What I want to do, is to draw lines connecting some of those sub-panels together.
However, while it seems like this should be simple, it's proven very frustrating. The best I've gotten, is to override the paintComponent function in the original jPanel as such:
panCharDisplay = new javax.swing.JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
paintLines(g);
}
};
And then draw the lines as such:
public void paintLines(Graphics g) {
g.setColor(Color.BLUE);
for (Character c : characters) {
if (c.female && c.spouse != null) {
g.drawLine(c.display.getX(), c.display.getY(), c.spouse.display.getX(), c.spouse.display.getY());
}
}
}
This works in a sense, in that it does technically draw the lines, in the right place, the right color, and so on, but only if I scroll away from where the line should be, and then scroll back. Whenever I drag a component around it causes weird graphics errors, as it draws only parts of the line and doesn't erase the ones before. The lines also show up below the sub-panels instead of over them, making them hidden a lot of the time.
I assume the reason for this is that I'm drawing the lines at the wrong time, and need to draw them after drawing the sub-panels, and also make sure that they are re-drawn every time the panels are dragged around.
Is there another place I can put in an override to make the lines show up more consistently? Another method I tried, was to make a class that extends JPanel, and try to use that to handle the drawing, but I couldn't get it to work at all.

Whenever I drag a component around it causes weird graphics errors, as it draws only parts of the line and doesn't erase the ones before.
You probably need to invoke repaint() on the panel's parent as you drag the panel around.
The lines also show up below the sub-panels instead of over them, making them hidden a lot of the time.
You should be able to override either the paint() or paintChildren() method instead of the paintComponent() method. Whichever method you override make sure to invoke super.XXX() first so that the default painting is done before you attempt to draw your lines.
Personally I like the lines painted below the component as is demonstrated in trashgod's GraphPanel example. The example does custom painting for the shapes, but I would guess the logic would be similar for the components.

You can get this JConnector project and use as is or adapt the sources as you need.

Related

Force full redraw of a Jpanel Java2D

My question is that i need to make a GUI that keeps updating becuse i get values that can change from a DB and i got some problems in the graphical area.
well im using Drawline and Drawstring from Graphics2D that print values that are found on the database, this strings and lines move and change value, so i need to call repaint(); with a timer to make them apper in the jpanel, the problem is that repaint(); is not removing the old painting in the background before painting, but when i resize all updates perfecly.
i know a way to clear but the background color goes away too so,
There is a way to update the jpanel removing old paintings and keep the deafult background color?
Not updated
After changing a coordenate and a label text to "AXIS Y" (repaint called automatically from a timer)
Thanks.
From the looks of your image, it looks like you're just forgetting to call super.paintComponent in the paintComponent method. What this does is repaint the background for you, so aren't left with the previous paint artifacts.
#Override
protected voud paintComponent(Graphics g) {
super.paintComponent(g);
}
Note: For future reference, though the images gave us a good picture, it always best to post a Minimal, Complete, and Verifiable example along with those images, so we don't have to make guesses (educated or not)

How to put paint component pieces on top of a background in Java?

We have a group project where we must create a turn based, 2 player, grid game for class, i.e. Chutes and Ladders. The whole project is done except for the fact that when we bring the background image up, the players pieces get painted behind the background, and are therefore not visible. Is there a way to get the pieces to show up on top of the background image? We are using imageIO for the image, GridLayout for the Grid, and then using PaintComponent to place the pieces on the grid. When we do not have the background image, the pieces show up on the Grid flawlessly.
using PaintComponent to place the pieces on the grid
Make sure to call the super's paintComponent(...) method first thing in your paintComponent override.
Make sure that your paintComponent method has no program logic inside of it.
Sometimes it's better to place your pieces in ImageIcons and the Icons in JLabels, and then place your JLabels on a Grid of JPanels. For example.
For more help, post code and give more details. To be honest, I'm a little surprised that you haven't even posted your paintComponent method code.

Auto calls to painting methods (Java) when I'm app-triggering (not interested in synchronously but async) in a loop

I'm developing some kind of videogame, so I am not interested in calling paint, repaint or any sort of those methods on each updating from keylistening, since they call also the update(Graphics g) method which cleans the whole screen. That's why I do want to #Override the update method, not allowing it to cleaning the screen at first. Doing this I can update what I want when I want.
However, sometimes it goes in a loop auto painting the components (such as jButtons) cleaning the screen(I couldn't track anything special happening whenever this occurs, I have already tried overriding some methods in order to catch which one's the troublesome and I couldn't find it, I'm likely missing something). I do not want this happening, because this auto painting cleans the screen which makes me draw everything once again. Moreover I don't feel comfortable with something looping until the player press any key. Do you have any clue? One solution could simply be using a timer with a boolean that each time a screen is completed and the next one is being loaded it calls update(g) from my JFrame (which contains the jPanel). But I would like something better..
Maybe I am doing something wrong, even if I tried to improve my painting methods thousand times surfing throughout the net and netbeans's suggs.
This is how my painting methods looks with some flags written and the ones that are called after running:
#Override public void paint(java.awt.Graphics g){
paintComponents(g);
System.out.println("Flag");
update(g);
}
#Override
public synchronized void update(Graphics g)
{
g.setColor(java.awt.Color.GREEN);
w.getDrawer().draw(g);
g.drawRect (0, 0, w.getActive().getW(), w.getActive().getH());
}`
The overriding on paint(Graphics g) method is not needed at all, just did it in order to see what was going on. I never called repaint() but update(getGraphics()) and it just spam Flags all around. Also thought that maybe I was making it run in a loop with paint and paintComponents, but deleting paintComponents(g) line helps not at all.
Any help would be welcome, since I am trying to make this project "serious". Thanks in advance.
Sergi.
By the way, w.getDrawer().draw(g); is just calling some entities (like 100) with something like g.drawImage(image, locationX, locationY, null) inside. I don't think it has anything to do with my prob.
..this auto painting cleans the screen which makes me draw everything once again.
Draw it to a BufferedImage displayed in a JLabel. When the data (the image) updates call label.repaint().
E.G. as seen in:
This answer to How to draw an image over another image?
This answer to Dynamic Graphics Object Painting.

Using a paintComponent with layout

How do I convert a paintComponent to something that I can manipulate with a layout in a JFrame?
So, I'm running into an issue. I haven't really been taught (and don't have access to a book) how to use layouts/GUI stuff in my courses yet.
My issue is this: I have a program that the user inputs a number. Based on this number, the program calculates a circle and draws it out with a paintComponent method that has a for loop inside of it. The "pixels" that the circle is drawn with are actually fillRect methods. The current method of getting a user-input that I am using is a JOptionPane showInputDialog. This is MOSTLY fine, but I want the user to be able to select from a set of pre-defined numbers. Somebody suggested that I use a JComboBox, but I don't know how I would convert the paintComponent to something that would be usable by a layout manager (which a JComboBox must use, as far as I've learned). I know the dimensions of the paintComponent (805px by 805px) and there is no situation where it will change. If I could get some help with this bit, I am confident that I can figure out using a layout manager myself.
Another way to paint (besides custom painting) is to paint to a BufferedImage. The image can then be displayed in a JLabel.
Examples:
Painting in a BufferedImage inside Swing A fairly complicated one.
Dynamic Graphics Object Painting Another one.
Yet another one.
You don't know the dimensions of paintComponent because it's a method, and methods don't have dimensions. You probably know the dimensions of a JPanel or a JFrame or whatever your component is.
You should separate the panel where you do the painting, and a different panel which would contain any comboboxes or other inputs you decide to put in. That way you can keep your drawing panel as is, and they won't interfere with each other. You'll want to search for the tutorial on LayoutManagers.

Drawing over a BufferedImage. repaint()

I have a component on which I'm drawing a BufferedImage on all the surface.
I would like to draw something more over it, following the mouse when it passes over the area.
To do it, I'm adding a MouseMotionListener on the component and implement mouseMove method. Inside mouseMoved method I'm calling repaint() at the end of the drawing of the drawing of the cursor image. I would like to know if there is a better way to do it, cause the image following the cursor is really small, and I'm repainting every thing each time.
Add a JLabel containing an Icon to the panel with the buffered image.
Then when you move the mouse you just change the location of the label. Swing will repaint the last location so the buffered image shows through, then it will repaint the label at the new location. So let Swing manage the repaint.
Since you know the coordinate of your mouse and the small image you gonna paint over your background, you can optimize like this [pseudo-code]:
void mouseMoved(event) {
lastCoordinates = currentCoordinates;
currentCoordinates = event.coordinates;
image.repaint(lastCoordinates.x, lastCoordinates.y, smallImage.width, smallImage.height);
image.repaint(currentCoordinates.x, currentCoordinates.y, smallImage.width, smallImage.height);
}
that way you only repaint the two regions you actually care about instead of the whole background.
Also, reading the javadoc it seems the code above my actually trigger 2 separate calls to painting stuff, which would be inefficient. You may want to try to pass in a 10 milliseconds value or so to make sure the 2 paints execute together.
Check out javadoc for repaint() that takes 4 and 5 arguments:
4-argument version
5-argument version

Categories