Buttons not visible until mouseover - java

I created a frame and panel (for Graphics) and add buttons to the panel. However, when I run my program buttons are not visible until I hover over them. Maybe it is something wrong with graphics methods.
How the problem can be solved?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main{
public static void main(String[] args) {
JFrame f = new JFrame();
f.setSize(600,500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
Panel panel = new Panel();
f.add(panel);
f.setVisible(true);
}
}
class Panel extends JPanel implements ActionListener{
int[] x = {200,400,300,200};
int[] y = {100,100,200,100};
JButton fillRed;
JButton fillBlack;
JButton cancel;
Panel(){
this.setLayout(null);
fillRed = new JButton("Red");
fillRed.setBounds(50, 400, 100, 50);
fillRed.addActionListener(this);
this.add(fillRed);
fillBlack = new JButton("Black");
fillBlack.setBounds(250, 400, 100, 50);
fillBlack.addActionListener(this);
this.add(fillBlack);
cancel = new JButton("Cancel");
cancel.setBounds(450,400,100,50);
cancel.addActionListener(this);
this.add(cancel);
}
public void paint(Graphics g) {
super.paintComponent(g);
g.drawPolygon(x,y,4);
}
public void fillRed(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.fillPolygon(x,y,4);
}
public void fillBlack(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillPolygon(x,y,4);
}
public void cancel(Graphics g) {
super.paintComponent(g);
g.drawPolygon(x,y,4);
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==fillRed) {
fillRed(getGraphics());
}
if(e.getSource()==fillBlack) {
fillBlack(getGraphics());
}
if(e.getSource()==cancel) {
cancel(getGraphics());
}
}
}

Your painting code is mostly wrong. For example:
public void paint(Graphics g) {
super.paintComponent(g);
g.drawPolygon(x,y,4);
}
If you need to override paint() then the first statement should be super.paint(g).
However, you should NOT override paint. For custom painting you override paintComponent(...) and then invoke super.paintComponent(g). Read the Swing tutorial on Custom Painting for more information and working examples.
public void fillBlack(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillPolygon(x,y,4);
}
Never invoke paintComponent(...) directly. If you need to change a property of a component then you invoke repaint() and Swing will invoke the painting methods.
if(e.getSource()==fillRed) {
fillRed(getGraphics());
}
Don't invoke getGraphics() on a Swing component. Painting is done by setting properties of your class and then you invoke repaint(). If you need to paint multiple objects then you need to keep track of each object you want to paint and then in the painting method you paint every object. Check out Custom Painting Approaches for example of how this can be done.

Related

Components render an unusal way

I have a custom JPanel class and I want it to paint several rectangles and texts in front of it's child components. I have overridden this method:
public void paint(Graphics g){
g = getComponentGraphics(g);
super.paint(g);
//paint my custom content
}
super.paint calls paintChildren whitch draws the child components. But the child components appear in front of my custom content, and they also sometimes Z fight with each other.
I'm absolutely clueless about what might be causing this.
NOTE: I use setComponentZOrder in my code, and my JPanel takes place in a JScrollPane.
EDIT: The components ZFight even if I never call the setComponentZOrder method.
EDIT 2:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.accessibility.Accessible;
import javax.accessibility.AccessibleSelection;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example extends JPanel{
private static final long serialVersionUID = 1L;
public static void main(String[] atgs){
JFrame frame = new JFrame("ZFightingExample");
frame.setSize(new Dimension(500,500));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ExamplePanel panel = new ExamplePanel();
frame.add(panel);
Example a = new Example(new Rectangle(5,5,50,50)),
b = new Example(new Rectangle(40,40,50,50));
panel.add(a);
panel.add(b);
frame.setVisible(true);
}
public Example(Rectangle bounds){
super();
setBounds(bounds);
}
public void paint(Graphics g){
super.setBackground(Color.GREEN);
g.fillRect(0, 0, getWidth()-1, getHeight()-1);
super.paint(g);
g.setColor(Color.BLACK);
g.drawRect(0, 0, getWidth()-1, getHeight()-1);
}
}
class ExamplePanel extends JPanel{
private static final long serialVersionUID = 1L;
public ExamplePanel(){
super(null);
accessibleContext = new Accessiblecontext();
};
protected class Accessiblecontext extends AccessibleJPanel implements AccessibleSelection{
private static final long serialVersionUID = 1L;
public int getAccessibleSelectionCount() {return 2;}
public Accessible getAccessibleSelection(int i) {return (Accessible)getComponent(i);}
public boolean isAccessibleChildSelected(int i) {return true;}
public void addAccessibleSelection(int i) {}
public void removeAccessibleSelection(int i) {}
public void clearAccessibleSelection() {}
public void selectAllAccessibleSelection() {}
}
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.BLUE);//Should be in front of the Green boxes...
g.drawRect(10, 10, 75, 75);
}
}
I want it to paint several rectangles and texts in front of it's child components.
Normally you override paintCompnent() to do custom painting.
The question is what does "in front" mean to you? If it means what I think it means then you need to do the painting after the child components have been painted. So you basic approach to override paint() is correct.
public void paint(Graphics g){
g = getComponentGraphics(g);
super.paint(g);
//paint my custom content
}
The problem with the above code is that you don't use the Graphics object passed to the painting method. So your code should be:
public void paint(Graphics g)
{
//g = getComponentGraphics(g);
super.paint(g); // use the Graphics object passed to the method
//paint my custom content
g.drawRect(10, 10, 20, 20);
}
I use setComponentZOrder in my code,
Why are you playing with ZOrder?
Edit:
g.setColor(Color.BLUE);//Should be in front of the Green boxes...
As I first stated in my answer, normally (99% of the time) custom painting is done by overriding the paintComponent() method of the panel.
The problem is with the Example class:
override paintComponent() not paint()
the first statement when you override a painting method should be super.???.
don't set properties of the class in the painting method.
So the code might look something like:
public Example(Rectangle bounds){
super();
setBounds(bounds);
setBackground(Color.GREEN);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(getBackground());
g.fillRect(0, 0, getWidth()-1, getHeight()-1);
g.setColor(Color.BLACK);
g.drawRect(0, 0, getWidth()-1, getHeight()-1);
}
Note you don't event need to do any custom painting with the Example class. Instead your code could be something like:
ExamplePanel panel = new ExamplePanel();
panel.setLayout( null ); // now you set the size/location of any component you add to the panel
JPanel example1 = new JPanel();
example1.setBackground( Color.GREEN );
example1.setBorder( new LineBorder(Color.BLACK) );
example1.setBounds( new Rectangle(....) );
panel.add(example1);
Also, another solution for the ExamplePanel class might be to use a JLayer. The JLayer class allows you to add all kinds of fancy decorations to a component. Check out the Swing tutorial on How to Decorate Components With The JLayer Class.

JLabel not showing when called in paint method

I have the following code:
public class Canvas extends JPanel{
JLabel label = new JLabel();
public void init()
{
label.setSize(100, 100);
label.setLocation(10, 10);
label.setText("lalallaalal");
this.add(label);
}
#Override
public void paint(Graphics g) {
super.paint(g);
paintRoad(g);
paintBorders(g);
paintEnemies(g, enemies);
paintPlayer(g);
}
I want the label to be redrawn every time the JPanel is repainted, but when I put this.add(label) at the end of paint method it doesn't show the label.
Any idea why?
paint() invokes paintComponent(). It's better to override paintComponent instead of paint.
protected void paintComponent(Graphics g)
A Closer Look at the Paint Mechanism
Instead of using the JLabel, try using the drawString(String str, int X, int y) method in the paint method.
public void paint(Graphics g){
g.drawString(label.getText(), 110, 110);
}

Can't print any string using drawString() in JFrame

I'm trying to find what is wrong with this short code. I can't print the String TEXT in my JFrame using drawString() method. Please Help . Only a plain white screen will appear if you run the program .
Code:
import javax.swing.*;
import java.awt.*;
public class sample extends JFrame
{
private JPanel panel;
public sample()
{
setSize(500,500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
panel =new JPanel();
Container mainP= getContentPane();
mainP.add(panel);
panel.setBounds(0,0,500,500);
panel.setBackground(Color.WHITE);
}
public void paintComponent(Graphics g)
{
Graphics2D eg = (Graphics2D)g;
eg.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
eg.setColor(Color.BLACK);
eg.drawString("TEXT", 40, 120);
}
public static void main(String args[])
{
new sample();
}
}
JFrame has no paintComponent method. So you aren't override anything, and not painting will be done.
On that note JPanel does have a paintComponent method, and you should be painting on a JComponent or JPanel, which do have the method. You don't want to paint on top-level containers like JFrame. (if you really need to know though, the correct method to override is paint for JFrame).
That being said, you should also call super.paintComponent inside the paintComponent method so you don't break the paint chain and leave paint artifacts.
Side Notes
As good practice, make use of the #Override annotation, so you know you are correctly overriding a method. You would've seen that paintComponent doesn't override one of JFrames methods.
setVisible(true) after add your components.
panel.setBounds(0,0,500,500); will do absolutely nothing, since the JFrame has a default BorderLayout
Follow Java naming convention and use capital letters for class names.
Run Swing apps from the Event Dispatch Thread. See more at Initial Threads
FINAL
import javax.swing.*;
import java.awt.*;
public class Sample extends JFrame {
private JPanel panel;
public Sample() {
setSize(500, 500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D eg = (Graphics2D) g;
eg.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
eg.setColor(Color.BLACK);
eg.drawString("TEXT", 40, 120);
}
};
Container mainP = getContentPane();
mainP.add(panel);
panel.setBackground(Color.WHITE);
setVisible(true);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new Sample();
}
});
}
}

Why JFrame is empty after my graphics

Why JFrame is empty after my graphics
package javaGame;
import java.awt.Graphics;
import javax.swing.JFrame;
public class javaGame extends JFrame {
public javaGame (){
setVisible(true);
setSize(250,250);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Java Game");
}
public void paint (Graphics g){
g.drawString("Hello world!", 75, 75);
}
public static void main (String[] args){
new javaGame ();
}
}
You are used to applets, where overriding paint will actually work. In a JFrame, the recommended technique is a little more complicated. Add this code to your constructor:
getContentPane().add(new JPanel() {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("Hello world!", 75, 75);
}
});
This creates an anonymous subclass of JPanel which overrides paintComponent to do some painting, then adds the JPanel to the frame. The call to super.paintComponent is important.
There are several other things that you should know are different from applets:
You need to call setVisible(true) to make the frame appear. This is mandatory for your program to work.
You should add setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) if you want the program to be closed if the window is closed. Highly recommended.
When you opening a new frame you should make it visible after validate or pack is applied to it, also call setVisible(true) at the end of the frame creation. The code for modification:
public void paint (Graphics g){
super.paint(g);
g.drawString("Hello world!", 75, 75);
}
1) Follow java code conventions javaGame should be JavaGame
2) Swing programs should override paintComponent() instead of overriding paint().
3) You should make custom painting in a JComponent like JPanel.
Change your code to for example something like this.
public class JavaGame {
private JFrame frame; //use composition instead of concrete inheritance
public JavaGame () {
jframe.setSize(250,250);
jframe.setResizable(false);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setTitle("Java Game");
jframe.add(new JPanel() {
#Override
public void paintComponent (Graphics g) {
super.paintComponent(g);
g.drawString("Hello world!", 75, 75);
}
});
jframe.pack(); //sizes the frame
jframe.setVisible(true);
}
public static void main (String[] args) {
SwingUTilities.invokeLater(new Runnable() {
#Override
public void run() {
new javaGame();
}
});
}
}

PaintComponent not working for drawing shapes

I was studying graphics and tried to use PaintComponent to draw some shapes, following is the code. I am trying for an hour but still its not working really can't get reason. What is the resolution to this simple problem?
public class MyPainting extends JPanel
{
public void PaintComponent (Graphics g)
{
super.paintComponent(g);
g.setColor(Color.RED);
g.drawRect(100, 100, 10, 20);
}
public static void main (String [] args)
{
MyPainting p = new MyPainting();
JFrame f= new JFrame();
f.setSize(300,300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(p);
f.setVisible(true);
}
}
When I run program there is empty JFrame, I did try it g.drawString, ImageIcon but every time nothing is visible.
The method PaintComponent is not defined in any of the super classes of JPanel. You want paintComponent
#Override
public void paintComponent (Graphics g)
and add the #Override annotation to allow compiler check for the correct method.

Categories

Resources