How to check these kinds of problem. When i checked the menus i have for a desktop application, some shows proper display of tooltip for close button which should always be at the front. But some are displayed at the back of the modal dialog.
Screenshot of the bug:
I kind of have the same problems as the one who posted this: https://coderanch.com/t/460688/java/Glasspanes-tooltips
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
class GlassPaneContent extends JPanel {
GlassPaneContent() {
setSize(200, 50);
ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);
JButton button = new JButton("A button");
button.setToolTipText("A tooltip");
add(button);
}
}
class GlassPane extends JPanel {
private static final Color BG_COLOR = new Color(0, 0, 0, 96);
private GlassPaneContent content = new GlassPaneContent();
public GlassPane() {
setLayout(null);
setOpaque(false);
add(content);
}
#Override
protected void paintComponent(Graphics g) {
g.setColor(BG_COLOR);
g.fillRect(0, 0, getWidth(), getHeight());
int x = (getWidth() - content.getWidth()) / 2;
int y = (getHeight() - content.getHeight()) / 2;
content.setLocation(x, y);
super.paintComponent(g);
}
}
public class MainWindow extends JFrame {
public MainWindow() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500, 500);
GlassPane gp = new GlassPane();
getRootPane().setGlassPane(gp);
gp.setVisible(true);
}
public static void main(String[] args) {
new MainWindow().setVisible(true);
}
}
We're using JAVA Swing. Kindly comment below if ever i need to post the codes. Thank you!
Try out this one:
public class MainWindow extends JFrame {
public MainWindow() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500, 500);
GlassPane gp = new GlassPane();
setContentPane(gp);
this.setVisible(true);
}
public static void main(String[] args) {
new MainWindow();
}
}
Related
I want to have a text field to input an integer, then select 1) Grow or 2) Shrink, and then click the button so that the circle gets redrawn on the screen based on the selected options.
I don't know why it isn't repaining. (Don't worry about the layout, just want to get it to work first)
My Frame:
public class Main {
public static void main(String[] args) {
var frame = new JFrame();
frame.setSize(400,400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
var circleComp = new circleComponent();
var panel1 = new JPanel();
var multiplierLabel = new JLabel("Grow Multiplier");
var multiplierField = new JTextField(20);
var radio1 = new JRadioButton("Grow Circle");
var radio2 = new JRadioButton("Shrink Circle");
var bg = new ButtonGroup();
bg.add(radio1);
bg.add(radio2);
JButton button = new JButton("Rivizato");
button.addActionListener(
new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(radio1.isSelected()){
rrComp.repaint(0,0,Integer.parseInt(multiplierField.getText())*rrComp.getWidth(), Integer.parseInt(multiplierField.getText())*rrComp.getHeight());
}
else if(radio2.isSelected()){
rrComp.repaint(0,0,Integer.parseInt(multiplierField.getText())/rrComp.getWidth(), Integer.parseInt(multiplierField.getText())/rrComp.getHeight());
}
}
}
);
panel1.add(multiplierLabel);
panel1.add(multiplierField);
panel1.add(button);
panel1.add(radio1);
panel1.add(radio2);
frame.add(panel1);
frame.add(circleComp);
}
}
My CircleComponent class:
public class CircleComponent extends JComponent {
public void paintComponent(Graphics g){
super.paintComponent(g);
var g2 = (Graphics2D) g;
var circle = new Ellipse2D.Double(0,0,100,100);
g2.draw(circle);
}
}
var circle = new Ellipse2D.Double(0,0,100,100); means that your circle will never change size.
You should also be careful with repaint(x, y, width, height) as it could leave regions of your component "dirty". Better to just use repaint.
As a conceptual example...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public final class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
private CirclePane circlePane;
public MainPane() {
setLayout(new BorderLayout());
JPanel actionsPane = new JPanel(new GridBagLayout());
JButton growButton = new JButton("Grow");
growButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
circlePane.grow();
}
});
JButton shrinkButton = new JButton("Shrink");
shrinkButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
circlePane.shrink();
}
});
actionsPane.add(growButton);
actionsPane.add(shrinkButton);
circlePane = new CirclePane();
add(circlePane);
add(actionsPane, BorderLayout.SOUTH);
}
}
public class CirclePane extends JPanel {
private Ellipse2D circle;
public CirclePane() {
circle = new Ellipse2D.Double(0, 0, 100, 100);
}
public void grow() {
double width = circle.getWidth() + 10;
double height = circle.getHeight() + 10;
circle.setFrame(0, 0, width, height);
repaint();
}
public void shrink() {
double width = Math.max(0, circle.getWidth() - 10);
double height = Math.max(0, circle.getHeight() - 10);
circle.setFrame(0, 0, width, height);
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
double x = (getWidth() - circle.getWidth()) / 2d;
double y = (getHeight() - circle.getHeight()) / 2d;
g2d.translate(x, y);
g2d.draw(circle);
g2d.dispose();
}
}
}
nb: I know I've not used JTextField to specify the size of the circle, that's on purpose. You will need to adapt your requirements to work in a similar way - can you see where you might pass parameters to the CirclePane?
I just started using Intelli J Idea and one of my first projects is to plot some geometric forms to a JPanel of a GUI defined in a form. In the end I want to plot some graphs. I found a tutorial where a class extending the JPanel was defined and the paintCompontent() method was overloaded.
public class MyPanel extends JPanel{
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
int y2 = (int)(40 * Math.random());
Line2D line = new Line2D.Double(10, 10, 60, y2);
Rectangle2D rectangle = new Rectangle2D.Double(200, 120, 70, 30);
Ellipse2D oval = new Ellipse2D.Double(400, 200, 40, 60);
g2.draw(line);
g2.setPaint(Color.RED);
g2.fill(rectangle);
g2.setPaint(Color.ORANGE);
g2.fill(oval);
}
}
This would run fine if I use it together with this code:
public class MainClass {
public static void main(String[] args) {
MyPanel s = new MyPanel();
JFrame f = new JFrame();
f.add(s);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(600, 400);
}
}
Then I tried combining this with a form I created using Intelli J Idea. And this is where I have problems. I would like to have a form with a button and a JPanel. When I press the button some geometric figures are being drawn on the JPanel defined in the form. I think my best try is like this:
public class MainWindow {
private JPanel panelMain;
private JButton buttonCalculate;
private JPanel panelPlot;
public MainWindow() {
buttonCalculate.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panelPlot = new MyPanel();
panelPlot.setBackground(Color.CYAN);
panelPlot.setSize(200, 200);
panelPlot.setVisible(true);
}
});
}
public static void main(String[] args) {
JFrame f = new JFrame("MyFirstGraphTool");
f.setContentPane(new MainWindow().panelMain);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(600, 400);
f.setVisible(true);
}
}
But simply saving my derived JPlane object to the bound property does not change anything.
And also the setBackgroundColor() method does not change anything.
Do you know any tutorials or more detailed explanation of how this can be done?
EDIT: Please find below an image of the component tree.
Component tree from Intelli J Idea
Thanks and kind regards,
David
You've made lots of mistakes in your code. I try to explain you, what's wrong.
public class MainWindow {
private JPanel panelMain; // panelMain is not initialized, so when you try to add it to any window/panel, you'll get a NullPointerException
private JButton buttonCalculate; // same as before. Also this button is not added to any container (window/panel)
private JPanel panelPlot; // panel is not added to any container
public MainWindow() {
buttonCalculate.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panelPlot = new MyPanel();
panelPlot.setBackground(Color.CYAN);
panelPlot.setSize(200, 200); // this code will not be honored because the layout manager will recalculate panel bounds.
// use setPreferredSize instead.
panelPlot.setVisible(true);
}
});
}
public static void main(String[] args) {
JFrame f = new JFrame("MyFirstGraphTool");
f.setContentPane(new MainWindow().panelMain);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(600, 400);
f.setVisible(true);
}
}
Here is the correct version of your class
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* <code>MainWindow</code>.
*/
public class MainWindow {
private JPanel panelMain = new JPanel();
private JButton buttonCalculate = new JButton("Calculate");
private JPanel panelPlot; // panel is not added to any container
public MainWindow() {
buttonCalculate.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panelPlot = new MyPanel();
panelPlot.setOpaque(true);
panelPlot.setBackground(Color.CYAN);
panelPlot.setPreferredSize(new Dimension(200, 200));
panelMain.add(panelPlot);
panelMain.revalidate(); // cause layout manager to recalculate component bounds
}
});
panelMain.add(buttonCalculate);
}
public static void main(String[] args) {
JFrame f = new JFrame("MyFirstGraphTool");
f.setContentPane(new MainWindow().panelMain);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(600, 400);
f.setVisible(true);
}
static class MyPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
int y2 = (int) (40 * Math.random());
Line2D line = new Line2D.Double(10, 10, 60, y2);
Rectangle2D rectangle = new Rectangle2D.Double(200, 120, 70, 30);
Ellipse2D oval = new Ellipse2D.Double(400, 200, 40, 60);
g2.draw(line);
g2.setPaint(Color.RED);
g2.fill(rectangle);
g2.setPaint(Color.ORANGE);
g2.fill(oval);
}
}
}
Please also read about layout managers in Swing
I've done several inspection and done research on how to make a single panel transparent so that the image underneath it will show but has been unsuccessful with panels on a JTabbedPane. I have setOpaque(false) and setBackground(new Color(0,0,0,20)) on both the panels of the JTabbedPane and also did the same on the JTabbedPane itself. However, I still can't get the image on the back of the tabbed pane to show. What else am I missing here?
tabbePane.java
package tabbedpanetransparencypractice;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.*;
public class tabbedPane extends JTabbedPane{
JPanel tab1panel = new JPanel();
JPanel tab2panel = new JPanel();
public tabbedPane(){
this.setPreferredSize(new Dimension(400,400));
this.setBackground(new Color(0,0,0,20));
this.setOpaque(false);
tab1panel.setBackground(new Color(0,0,0,20));
tab2panel.setBackground(new Color(0,0,0,20));
tab1panel.setOpaque(false);
tab2panel.setOpaque(false);
this.addTab("Tab 1", tab1panel);
this.addTab("Tab 2", tab2panel);
}
}
topPanel.java
package tabbedpanetransparencypractice;
import javax.swing.*;
import java.awt.*;
public class topPanel extends JPanel{
Image myBG = new ImageIcon(getClass().getClassLoader().getResource("Assets/loginBg.jpg")).getImage();
#Override
public void paintComponent(Graphics g){
g.drawImage(myBG,0,0,getWidth(),getHeight(),this);
}
public topPanel(){
addTabbedPane();
}
public void addTabbedPane(){
tabbedPane tabbedpane = new tabbedPane();
this.add(tabbedpane);
}
}
frame.java
package tabbedpanetransparencypractice;
import java.awt.Dimension;
import javax.swing.*;
public class frame extends JFrame{
topPanel myPanel = new topPanel();
public frame(){
this.setPreferredSize(new Dimension(600,600));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.pack();
this.setLocationRelativeTo(null);
addComponents();
}
final void addComponents(){
this.setContentPane(myPanel);
}
}
main.java
package tabbedpanetransparencypractice;
public class main {
public static void main(String[] args) {
frame myFrame = new frame();
}
}
This is the output I get (I want the tab1 and tab2 to be transparent to reveal the bg image underneath)
I'd appreciate any help. Thanks.
First, Swing DOES NOT know how to deal with component's whose background colors are alpha based but which are opaque. Swing only knows how to deal with fully opaque and fully transparent components.
Using alpha based colors will generate weird and random paint artefacts. The simple answer is, you should never apply a alpha based color to a component's background (the only exception is JFrame - thanks Sun :P)
The primary solution is, fake it.
That is, make the component transparent (setOpaque(false)) and paint the background at a reduced alpha level. You can then use a alpha based color (because the component is no longer reliant on the color, as it's transparent), but I tend to just use a AlphaComposite as it's generally easier to control and manipulate.
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
BackgroundPane bp = new BackgroundPane();
bp.setLayout(new BorderLayout());
bp.setBorder(new EmptyBorder(20, 20, 20, 20));
SeeThroughTabbedPane tp = new SeeThroughTabbedPane();
tp.setAlpha(0.5f);
tp.addTab("Tab 1", new TestPane("I be see through"));
tp.addTab("Tab 2", new TestPane("But you can't see me"));
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(bp);
frame.add(tp);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane(String text) {
setOpaque(false);
setLayout(new GridBagLayout());
JLabel label = new JLabel(text);
label.setForeground(Color.WHITE);
add(label);
}
}
public class BackgroundPane extends JPanel {
private BufferedImage bg;
public BackgroundPane() {
try {
bg = ImageIO.read(new File("/Volumes/Disk02/Dropbox/MegaTokyo/megatokyo_omnibus_1_3_cover_by_fredrin-d4oupef 50%.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return bg == null ? new Dimension(200, 200) : new Dimension(bg.getWidth(), bg.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bg != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - bg.getWidth()) / 2;
int y = (getHeight() - bg.getHeight()) / 2;
g2d.drawImage(bg, x, y, this);
g2d.dispose();
}
}
}
public class SeeThroughTabbedPane extends JTabbedPane {
private float alpha;
public SeeThroughTabbedPane() {
setOpaque(false);
setAlpha(1f);
}
public void setAlpha(float value) {
if (alpha != value) {
float old = alpha;
this.alpha = value;
firePropertyChange("alpha", old, alpha);
repaint();
}
}
public float getAlpha() {
return alpha;
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(getBackground());
g2d.setComposite(AlphaComposite.SrcOver.derive(getAlpha()));
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
super.paintComponent(g);
}
}
}
Remember, anything you added to the JTabbedPane which is still opaque will remain so, not in my TestPane's constructor, I set the panel's opaque state to false
You might also like to take a look at Painting in AWT and Swing and Performing Custom Painting
You might be able to use UIManager.put("TabbedPane.contentAreaColor", new Color(255, 255, 0, 100));
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TransparentTabbedPaneTest {
public JComponent makeUI() {
Color bgc = new Color(110, 110, 0, 100);
Color fgc = new Color(255, 255, 0, 100);
UIManager.put("TabbedPane.shadow", fgc);
UIManager.put("TabbedPane.darkShadow", fgc);
UIManager.put("TabbedPane.light", fgc);
UIManager.put("TabbedPane.highlight", fgc);
UIManager.put("TabbedPane.tabAreaBackground", fgc);
UIManager.put("TabbedPane.unselectedBackground", fgc);
UIManager.put("TabbedPane.background", bgc);
UIManager.put("TabbedPane.foreground", Color.WHITE);
UIManager.put("TabbedPane.focus", fgc);
UIManager.put("TabbedPane.contentAreaColor", fgc);
UIManager.put("TabbedPane.selected", fgc);
UIManager.put("TabbedPane.selectHighlight", fgc);
UIManager.put("TabbedPane.borderHightlightColor", fgc);
JTabbedPane tabs = new JTabbedPane();
JPanel tab1panel = new JPanel();
tab1panel.setBackground(new Color(0, 220, 220, 50));
JPanel tab2panel = new JPanel();
tab2panel.setBackground(new Color(220, 0, 0, 50));
JPanel tab3panel = new JPanel();
tab3panel.setBackground(new Color(0, 0, 220, 50));
JCheckBox cb = new JCheckBox("setOpaque(false)");
cb.setOpaque(false);
tab3panel.add(cb);
tab3panel.add(new JCheckBox("setOpaque(true)"));
tabs.addTab("Tab 1", tab1panel);
tabs.addTab("Tab 2", tab2panel);
tabs.addTab("Tab 3", new AlphaContainer(tab3panel));
JPanel p = new JPanel(new BorderLayout()) {
private Image myBG = new ImageIcon(getClass().getResource("test.png")).getImage();
#Override public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(myBG, 0, 0, getWidth(), getHeight(), this);
}
};
p.add(tabs);
p.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
return p;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new TransparentTabbedPaneTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
//https://tips4java.wordpress.com/2009/05/31/backgrounds-with-transparency/
class AlphaContainer extends JComponent {
private JComponent component;
public AlphaContainer(JComponent component) {
this.component = component;
setLayout( new BorderLayout() );
setOpaque( false );
component.setOpaque( false );
add( component );
}
/**
* Paint the background using the background Color of the
* contained component
*/
#Override
public void paintComponent(Graphics g) {
g.setColor( component.getBackground() );
g.fillRect(0, 0, getWidth(), getHeight());
}
}
I am trying to draw a rectangle in the class "Graphics", but for some reason the rectangle does not appear, but the program returns no errors. I have never experience issues such as this before so I am rather confused.
Main()
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main
{
public Main()
{
JFrame window = new JFrame();
Sound soundCall = new Sound();
Graphics graphicsCall = new Graphics();
final JPanel container = new JPanel();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(container);
window.setSize(600, 400);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.setResizable(false);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new Main();
}
});
}
Graphics()
import java.awt.Color;
import java.awt.Graphics2D;
import javax.swing.JPanel;
public class Graphics extends JPanel
{
public void paintComponent(java.awt.Graphics g)
{
super.paintComponent(g);
g.setColor(Color.GRAY);
g.drawRect(500, 500, 500, 500);
}
}
EDIT FOR HOVERCRAFT
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main
{
public Main()
{
JFrame window = new JFrame();
Sound soundCall = new Sound();
Draw drawCall = new Draw();
final JPanel container = new JPanel();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(drawCall);
window.setSize(600, 400);
window.setLocationRelativeTo(null);
window.setVisible(true);
window.setResizable(false);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new Main();
}
});
}
}
Through adding this window.getContentPane().add(drawCall); asks me to change drawCall to a Component
EDIT 2:
public class Draw
{
public class Graphics extends JPanel
{
public void paintComponent(java.awt.Graphics g)
{
super.paintComponent(g);
g.setColor(Color.GRAY);
g.drawRect(0, 0, 500, 500);
}
}
}
ERROR
The method add(Component) in the type Container is not applicable for the arguments (Draw)
You add your graphicsCall variable to nothing, and so it will not be displayed. Solution: add it to a container such as that JPanel that you just created, or perhaps directly to the JFrame's contentPane.
i.e., change this:
JFrame window = new JFrame();
Sound soundCall = new Sound();
Graphics graphicsCall = new Graphics();
final JPanel container = new JPanel();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(container);
to this:
JFrame window = new JFrame();
Sound soundCall = new Sound();
Graphics graphicsCall = new Graphics();
// final JPanel container = new JPanel();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.getContentPane().add(soundCall);
As an aside, you will want to re-name that class from Graphics to something else, or else you risk confusing yourself or your compiler since there already exists a critical Java class with that name.
Also, avoid using setSize(...). Better to have your drawing JPanel override getPreferredSize() and to call pack() on your JFrame.
Edit
As per MadProgrammer's astute observation, you're drawing outside of the bounds of your component.
Edit 2
Regarding your latest code, this:
public class Draw
{
public class Graphics extends JPanel
{
public void paintComponent(java.awt.Graphics g)
{
super.paintComponent(g);
g.setColor(Color.GRAY);
g.drawRect(0, 0, 500, 500);
}
}
}
is useless dreck. Why are you needlessly wrapping a class inside of a class? Instead why not simply:
public class Draw extends JPanel {
public void paintComponent(java.awt.Graphics g)
{
super.paintComponent(g);
g.setColor(Color.GRAY);
g.drawRect(0, 0, 500, 500);
}
#Override
public Dimension getPreferredSize() {
// return an appropriate Dimension here
}
}
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
class Painter extends JPanel implements ActionListener{
private int x = 30, y = 30;
//remove the blocked comment to make it run
/*public Painter(){
Buttons b = new Buttons(new String("Click to paint"));
b.addActionListener(this);
add(b);
}*/
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(new Color(44,55,66));
g.fillRect(200,200,x,y);
}
public void actionPerformed(ActionEvent e){
x = 600;
y = 600;
repaint();
}
}
import javax.swing.JButton;
public class Buttons extends JButton{
public Buttons(String Tag){
super(Tag);
setBounds(20, 20, 150, 50);
Painter p = new Painter();//comment it out
addActionListener(p);//comment it out
}
}
import java.awt.Color;
import javax.swing.JFrame;
public class Window extends JFrame{
public Window(){
Buttons b = new Buttons("Click Me");//comment it out
Painter p = new Painter();
getContentPane().add(b);//comment it out
getContentPane().add(p);
getContentPane().setBackground(Color.WHITE);
setSize(700,700);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}
public class PaintOnEvent {
public static void main(String[] args){
Window w = new Window();
}
}
This is a testing program. I registered the Painter class to the Buttons class using addActionListener() method, then why doesn't it still can't look for the actionperformed method? Then when I created a button in the painter class itself, it worked. Why is it so?
You have at least two Painter objects. The one being displayed is not the one being used as an ActionListener object. For instance, what if you pass a reference to the Painter object that is being displayed to your Button class like so (changes are denoted by \!! comments):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class Painter extends JPanel implements ActionListener {
private int x = 30, y = 30;
// remove the blocked comment to make it run
/*
* public Painter(){ Buttons b = new Buttons(new String("Click to paint"));
* b.addActionListener(this); add(b); }
*/
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(new Color(44, 55, 66));
g.fillRect(200, 200, x, y);
}
public void actionPerformed(ActionEvent e) {
x = 600;
y = 600;
repaint();
}
}
class Buttons extends JButton {
public Buttons(String Tag, Painter p) { \\!!
super(Tag);
setBounds(20, 20, 150, 50);
// !! Painter p = new Painter();// comment it out
addActionListener(p);// comment it out
}
}
class Window extends JFrame {
public Window() {
Painter p = new Painter();// !!
Buttons b = new Buttons("Click Me", p);// comment it out //!!
getContentPane().add(b);// comment it out
getContentPane().add(p);
getContentPane().setBackground(Color.WHITE);
setSize(700, 700);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}
public class PaintOnEvent {
public static void main(String[] args) {
Window w = new Window();
}
}
An example that takes into consideration the BorderLayout of the contentPane is as follows:
class Window extends JFrame {
public Window() {
Painter p = new Painter();
Buttons b = new Buttons("Click Me", p); // !!
b.setPreferredSize(new Dimension(150, 50));
JPanel btnPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); // !!
btnPanel.setOpaque(false); // !!
btnPanel.add((b)); // !!
p.setOpaque(false); // !!
getContentPane().add(btnPanel, BorderLayout.NORTH); // !!
getContentPane().add(p, BorderLayout.CENTER); // !!
getContentPane().setBackground(Color.WHITE);
((JPanel) getContentPane()).setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); // !!
// !! setSize(700, 700);
setPreferredSize(new Dimension(700, 700)); // !!
pack(); // !!
setLocationRelativeTo(null); // !!
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}