Disable painting on a JPanel - java

I'm trying to completely disable all painting and refreshing on a portion of a JFrame. I got the desired effect on the entire JFrame by simply overriding public void paint(Graphics) like so:
import javax.swing.*;
class Test extends JFrame {
Test () {
setBounds(20,20, 100,100);
setVisible(true);
}
//This disables all painting and refreshing ON A JFRAME.
//Just doing this on a JPanel doesn't work.
public void paint (Graphics g) {}
public static void main (String[] args)
{ new Test(); }
}
I want this same effect, but only on a particular region of the JFrame. I want to be able to add GUI components like normal to the rest of the frame. I've tried disabling double buffering (using JPanel's constructor) and overriding the following methods (extending both JPanel and JComponent) like so:
public class DontRefresh extends JComponent/JPanel {
public void paint (Graphics g) {}
public void paintComponent (Graphics g) {}
public void repaint () {}
public void update (Graphics g) {}
public void updateUI () {}
}
and i also tried disabling refresh via:
DontRefresh component = new DontRefresh();
RepaintManager.currentManager(component).markCompletelyClean(component);
but nothing worked.

Well, without knowing exactly what you're doing I would recommend you have a "filler panel" (just a JPanel you don't do anything with) in the space you don't want anything to appear and then have other panels for everything else.
So say you have a JFrame. If you wanted the top right corner to never display anything, you could fill the JFrame with 4 JPanels, one in each corner (or 3 with one on the left, one in the top right corner and one in the bottom right corner). Then put all you swing components in the other panels. I don't know if this will accomplish your purpose, but I'm not totally certain what you're purpose is, so that's the best I can do :) I hope it helps!

Related

Japplet shapes does not shown in Applet

Im working with eclipse.
My Code:
import javax.swing.JApplet;
import java.awt.*;
public class Einstein extends JApplet
{
public void pain(Graphics page)
{
page.drawRect(60,60,40,40); // Square
page.drawString("Out of clutter, find simplicity. " , 110, 70);
}
}
The rectangle and text does not shown in the applet.
what could be the problem?
public void pain(Graphics page) - interesting choice of naming...
I believe the method you're looking for is paint
#Override
public void paint(Graphics g) {
super.paint(g);
//...
}
Make sure you call super.paint before performing any custom painting, otherwise you could end up with a bunch of nasty paint artefacts.
Having said that. Consider using a custom component, extending from JPanel for example, and override it's paintComponent method instead, then add this component to your applet.
You gain the benefit of the double buffering support of Swing for free and the freedom to move you component to another container, like a JFrame or other container for example, making it far more re-usable

Clearing drawings on Jframe

I am making a game in which I move a square with my mouse, but when I move my mouse the old squares do not delete, which results in a trail of squares. I would like it to only have the one square which is following my mouse. This is currently my code. I have read to use paintcomponents but I am not sure how to use it since I am still a beginner.
This is in my "GamePanel" Class
public void mouseMoved(MouseEvent m) {
Graphics g= this.getGraphics();
h.changeX(m.getX());
h.changeY(m.getY());
h.drawHero(g);
}
This is in my "Hero" Class
public void drawHero(Graphics g){
g.drawImage(heroPic,stX,stY,null); //heroPic is a picture I imported
Don't use the this.getGraphics(). That is something you will definitely not want to to do, since it produces artifacts (as you mentioned).
It would be better to store the mouse position as a variable, then handle all the rendering when the paintComponent(Graphics) method has been called. Be sure to also call super.paintComponent(Graphics) to get rid of artifacts.
Generally, you should only handle graphics inside the paintComponent(Graphics) method and in any methods that are called only from the paintComponent(Graphics) method.
Here is a question which touches on why you should avoid Component#getGraphics(): Drawing an object using getGraphics() without extending JFrame
Here is another question I answered revolving around rendering with graphics: Java JFrame draw
Use a seperate class that extends JPanel :
class DrawPane extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(heroPic, x, y, this);
}
}
Then create a variable that will hold this class object :
DrawPane dp = new DrawPane();
after that set the variable to the contence pane. :
JFrame.setContencePane(dp);
Now to repaint this do :
dp.repaint();
Do not worry about the 'Graphics g' you wont have to input anything.

Using awt.Graphics in a method

I created a class called Test, most likely where I went wrong.
import javax.swing.JPanel;
import java.awt.*;
public class Test extends JPanel {
Graphics grap;
public void sun()
{
super.paintComponent(grap);
grap.setColor(Color.YELLOW);
grap.fillOval(0,0,20,20);
}
}
As you can see I want to paint a yellow "Oval" in the top left corner of the panel using a method but I did not use a PaintComponent method. Now I try to implement it in my Paint component method which is in a class called Painting.
//import...;
public class Painting extends JPanel{
protected void paintComponent(Graphics g)
{
Test test = new Test();
test.sun();
}
And now i created a main window that will create a panel and display the yellow oval.
//import...
public class main extends JFrame{
public static main(String [] args){
JFrame window = new JFrame();
window.add(new Painting());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(100,100);
window.setLocationRelativeTo(null);
window.setVisible(true);
}
}
But this does not work. I have a feeling that it is the sun method in test. How would I get this to work? I have looked in all the java books and cant find anything that can help.
Please note that I do not what to add parameters to the method.
Thank You
Tom.
Few points to be noted here:
Never call super.paintComponent by yourself except within the overriden paintComponent method itself.
If you want to do some Graphics activities then override the paintComponent method and draw graphics over there
When you are overriding paintComponent method then the first statement within the method should be super.paintComponent(g).
Now, going by all above points your code should now be like this:
public class Test extends JPanel {
public void paintComponent(Graphics grap)
{
super.paintComponent(grap);
grap.setColor(Color.YELLOW);
grap.fillOval(0,0,20,20);
}
}
And your Painting class should be like this:
public class Painting extends JPanel{
Test test;
public Painting()
{
test = new Test();
setLayout(new BorderLayout());
add(test);
}
}
If i want to draw 50 ovals on different places then i would have a problem with extensive code
Then you would keep a List of the ovals that you want to paint. See Custom Painting Approaches which paints a bunch of Rectangles on a panel. All the code does is loop through the ArrayList to paint the Rectangle. Only a couple of lines of code are required.

Why won't the JPanel change color and stay that way?

I'm working on a assignment for school but I got a problem :P.
I got this code:
public void mouseEntered(MouseEvent e) {
MyPanel b = (MyPanel)e.getSource();
System.out.println("ID: "+b.getId()+"");
b.setColor(Color.blue);
}
In the MyPanel object I got:
public void setColor(Color kleur) {
if(this.getBackground()==Color.white) {
this.setBackground(kleur);
repaint();
}
}
When I enter the panel with my mouse the color flashes that I entered. But I want it to stay the color so I can draw a trail in a Jform with 500 Jpanels(I've added them to a ArrayList but this part works just fine)
What am I doing wrong?
Based on #ErickRobertson's comment on the question, I guess the problem is the following:
Your MyPanel replaces the JPanel#paintComponents() method. Is that possible? If so, you could do the following. In your MyPanel#setColor(Color) method, you don't set the background, but a field containing your new background color:
private Color backgroundColor = Color.white;
public void setColor(Color kleur) {
backgroundColor = kleur;
repaint();
}
Then, in your MyPanel#paintComponents(Graphics):
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// draw background
g.setColor(backgroundColor);
g.fillRect(0, 0, getWidth(), getHeight());
// draw your stuff here
}
Make sure that only one JPanel is visible at a time.
When you add the JPanels to their parent, are they all going on top of each other? If so, then when you call repaint() on one of them, it's being repainted immediately and you can see it as blue. But as soon as the whole window repaints again, the JPanels are painted in the order they have been added and the last one is ultimately painted on top. This panel still has a white background, so that's what you're seeing.
Make sure only one of these panels are visible at a time, or that you have some plan in place to manage these panels so that only one of them are visible. Otherwise, make sure they are laid out in a grid or some other way so they don't appear on top of each other.
Where is your MouseListener implemented, since you are getting the panel from the MouseEvent. It's easier to have the panels implement the MouseListener and let them decide when to change color for themselves.
class Panel extends JPanel implements MouseListener {
public Panel() {
// Make sure the listener listens
addMouseListener(this);
}
#Override
public void mouseEntered(MouseEvent e) {
setColor(Color.blue);
}
// ... other mouselisteners can be ignored or implemented as needed
}
You can still keep a reference to some other class if you need it to be notified of a mouseenter. Just create a private member and set the reference in the constructor.
public void setColor(Color kleur) {
if(this.getBackground()==Color.white) {
this.setBackground(kleur);
repaint();
}
}
dont use == repalce with equals and try invalidate(. Your code is basically saying only replace background if background is white ???

BG image with Swing without overriding paintComponent

I'm currently designing a menu with several screens with multiple buttons on each screen. To use buttons on top of the background image, which is in a jLabel (by default, I can't put buttons on TOP of the jLabel), I used GridBagLayout with two panels/menu screen, one panel containing the buttons (opaque = false) and one panel with the background image, or jLabel. In order to switch the current panels being displayed, depending on where the user is in the menu, I made each menu screen (aka. every 2 panels) in separate methods, not classes.
Now, I've come to the point where I'm working on parts of the interface that are unnecessarily complicated, and I don't feel GridBag will serve my purposes, so I was wondering if there was a different way to draw my background image, still being able to use my buttons on top of the image.
The most popular way I looked up was overriding the paintComponent method, but I can't do that, since I've made my JPanels in separate methods, not classes. They're all contained in my original JFrame.
Help would be greatly appreciated, thank you!
Just added this code, but my background remains white for some reason? Trying the other suggestion right now, thanks guys!
private void mainPanel() {
icon = new ImageIcon(getClass().getResource("/phantasma/menuv1.png"));
mainContainer1 = new javax.swing.JPanel() {
#Override
protected void paintComponent(Graphics g) {
g.drawImage(icon.getImage(), 0,0, null);
super.paintComponent(g);
}
};
BG image with Swing without overriding paintComponent
I have no idea why all the postings suggest doing custom painting for this. You would only do custom painting if you need to automatically scale the background image.
If you want the image painted at its real size then use a JLabel.
I can't put buttons on TOP of the jLabel),
Sure you can. Just set a LayoutManager for the JLabel and then you can add any component to it the same way you add components to a panel.
In my comment above I state:
You can always create an anonymous inner JPanel-derived class and override the paintComponent method there if need be.
As an example of what I mean, you can override paintComponent in any JPanel that you create whether it's derived from a stand-alone class or created within a method. For e.g.,
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;
public class AnonInnerPanel {
private static void createAndShowGui() {
JPanel mainPanel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
};
JFrame frame = new JFrame("AnonInnerPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Categories

Resources