Java Graphics Only Paint on Button Click - java

I'm not sure how java graphics work. It seems
to be executing something itself so I am trying to break it
down.
I'm trying to create the blank JPanel and then only draw to it
once the JButton has been clicked but it doesn't work
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
public class testGui {
// global ======================================================================
static gui gc_gui;
// main ========================================================================
public static void main(String[] args) {
gc_gui = new gui();
gc_gui.cv_frame.setVisible(true);
listeners();
}
// action listeners ============================================================
public static void listeners() {
ActionListener ll_square = new ActionListener() {
public void actionPerformed(ActionEvent event) {
gc_gui.cv_content.draw(graphic);
}
};
gc_gui.cv_button.addActionListener(ll_square);
}
// gui =========================================================================
public static class gui {
JFrame cv_frame;
JButton cv_button;
content cv_content;
public gui() {
cv_frame = new JFrame();
cv_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cv_frame.setTitle("Test GUI");
cv_frame.setSize(600, 400);
cv_frame.setLayout(new FlowLayout());
cv_button = new JButton("Square");
cv_content = new content();
cv_content.setBackground(Color.BLACK);
cv_content.setPreferredSize(new Dimension(500, 300));
cv_frame.add(cv_button);
cv_frame.add(cv_content);
}
}
// content =====================================================================
public static class content extends JPanel {
public void paint(Graphics graphic) {
super.paint(graphic);
}
public void update() {
super.repaint();
}
public void draw(Graphics graphic) {
Graphics2D graphic2D = (Graphics2D) graphic;
graphic2D.setPaint(Color.RED);
graphic2D.fillRect(10, 10, 100, 100);
}
}
}
I create the content JPanel without the draw function being
called and then I try to call it using my ActionListener
although it is crashing because of the graphic variable.
What is the correct way to use the java graphics utility?
UPDATE
Maybe I'm not asking this question right but it is possible to
create a blank image.
Then draw additional images to that images (squares) after a button
has been clicked?
not just updating the dimensions using global variables but generating
new images to that existing image

but it is possible to create a blank image. Then draw additional images to that images (squares) after a button has been clicked?
Check out Custom Painting Approaches for two common ways to do painting.
The example allows you to draws Rectangles with the mouse. In your case the logic will be simpler as you would just invoke the addRectangle(...) method when you click a button. Of course you need to set the size/location of the Rectangle somehow.

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
public class TestGui {
public static Content content;
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Test GUI");
frame.setSize(429, 385);
frame.getContentPane().setLayout(null);
JButton cv_button = new JButton("Square");
cv_button.setBounds(10, 159, 70, 23);
frame.getContentPane().add(cv_button);
cv_button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Content.isToDraw = true;
content.paintImmediately(content.getBounds());
Content.isToDraw = false;
}
});
JButton cv_buttonClear = new JButton("Clear");
cv_buttonClear.setBounds(10, 179, 70, 23);
frame.getContentPane().add(cv_buttonClear);
cv_buttonClear.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
content.paintImmediately(content.getBounds());
}
});
content = new Content();
content.setBorder(new LineBorder(new Color(0, 0, 0)));
content.setBounds(87, 11, 287, 312);
frame.getContentPane().add(content);
frame.setVisible(true);
}
}
class Content extends JPanel {
public static Boolean isToDraw = false;
public void paintComponent(Graphics arg0) {
if (isToDraw) {
arg0.setColor(Color.RED);
arg0.fillRect(0, 0, getWidth(), getHeight());
} else {
super.paintComponent(arg0);
}
}
}

Related

Gui does not paint the panel

hi guys i have wird problem i have here my GUI class is working good at begining just by showing loggin screen. but i have second class called DataLayer that is responsible for reading from files and creating objets with infromaton.
the problem is that when i try to create new DataLayer() in GUI class the panel doesn show until i resize screen and even after that the keylistener doesn't work.
`package View;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
import dto.DataLayer;
import dto.ProductDTO;
public class GUI extends JPanel {
private DataLayer dt;
private ComponentAbstract korzen;
private GUI self;
public GUI() {
this.setFocusable(true);
this.dt=new DataLayer();`
self=this;
this.stworz_PanelLogowania();
this.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
korzen.tryPressKey(e);
repaint();
}
});
this.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
korzen.tryClick(e.getX(), e.getY());
repaint();
}
});
this.repaint();
}
#Override
protected void paintComponent(Graphics g ) {
super.paintComponent(g);
korzen.repaint();
System.out.println("omatko");
korzen.draw((Graphics2D)g);
}
private void zmien_panel(ComponentAbstract newkorzen){
korzen=newkorzen;
self.repaint();
}
private void stworz_PanelLogowania(){
LinearPanel lp=new LinearPanel(220, 10, 300, 300);
lp.setOrientarion(Orientation.VERTICAL);
LinearPanel labels_panel=new LinearPanel(220,0,50,80);
labels_panel.setOrientarion(Orientation.VERTICAL);
labels_panel.addComponent(new Label(0, 0, 350, 40, "Witamy w castorama APP"));
lp.setPadding(6);
LinearPanel textpanel1=new LinearPanel(0, 0, 350, 80);
textpanel1.setPadding(0);
textpanel1.addComponent(new Label(0,0,350,40,"Login:"));
textpanel1.addComponent(new TextBox(0, 0, 350, 40));
LinearPanel textpanel2=new LinearPanel(0, 0, 35, 80);
textpanel2.setPadding(0);
textpanel2.addComponent(new Label(0,0,350,40,"Hasło:"));
textpanel2.addComponent(new TextBox(0, 0, 350, 40));
lp.addComponent(labels_panel);
lp.addComponent(textpanel1);
lp.addComponent(textpanel2);
LinearPanel buttons_panel=new LinearPanel(00, 00, 350, 40);
buttons_panel.setOrientarion(Orientation.HORIZONTAL);
buttons_panel.addComponent(new Button(170,40,"Zaloguj"){
#Override
public void onClick() {
TextBox tlogin=(TextBox)korzen.getComponent(1).getComponent(1);
TextBox tpass=(TextBox)korzen.getComponent(2).getComponent(1);
if(dt.autoryzacja_uzytkownika(tlogin.getText(), tpass.getText())){
System.out.println("Puszczamy typa");
}
}
});
buttons_panel.addComponent(new Button(170,40,"Wyjdz"){
#Override
public void onClick() {
System.exit(0);
}
});
lp.addComponent(buttons_panel);
korzen=lp;
System.out.println("kuniec");
}
private void stworz_panelGlowny(){
LinearPanel glowny=new LinearPanel(220,0,50,80);
}
}
the problem is that when i try to create new DataLayer() in GUI class the panel doesn show until i resize screen
When you add (or remove) components from a visible GUI the basic code is:
panel.add(...);
panel.revalidate(); // to invoke the layout manager
panel.repaint(); // to paint the components.
even after that the keylistener doesn't work.
Probably because some other component has focus and KeyEvents area only dispatched to the component with focus. Try using the requestFocusInWindow() method on the panel.
panel.requestFocus

Calling repaint() draws the new shape, but leaves the old shape there

I'm sure this is a simple answer, but I can't figure it out.
I am trying to make a basic shape that I can control in a window. Obviously it will be more involved when the whole project is complete, but I am working on the early steps still. I am using WindowBuilder to make the layout, and have a JPanel and a JButton. The JPanel draws a rectangle, and has a method to move it. The JButton calles that moving command. And that's it. The problem is in the repaint. The shape keeps all old versions of itself, and the button makes weird copies of itself. All these go away when I resize the window, which I thought was the same as calling repaint. Again, I'm sure is something simple I am missing. Below are my 2 classes.
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.BorderLayout;
import javax.swing.JPanel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Drawing {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Drawing window = new Drawing();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Drawing() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
drawpanel panel = new drawpanel();
panel.setBounds(58, 68, 318, 182);
frame.getContentPane().add(panel);
JButton btnMove = new JButton("move");
btnMove.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
panel.moves();
}
});
btnMove.setBounds(169, 34, 89, 23);
frame.getContentPane().add(btnMove);
}
}
^ This one, besides the buttonListener, was autocreated by WindowBuilder.
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class drawpanel extends JPanel {
int x = 50, y = 50;
int sizeX = 50, sizeY = 50;
public void paintComponent( Graphics g) {
super.paintComponents(g);
g.setColor(Color.BLACK);
g.drawRect(x, y, sizeX, sizeY);
}
public void moves() {
x +=5;
repaint();
}
}
^ This one has my drawing of the shape and the moving/repainting method. It was written mostly from other examples I found on this site.
Thanks to any help in advanced.
public void paintComponent(Graphics g) {
super.paintComponents(g); // wrong method! (Should not be PLURAL)
Should be:
public void paintComponent(Graphics g) {
super.paintComponent(g); // correct method!

Java GUI: Image will be overwritten, Path the same -> show it in the frame (image still the same)

I want to show a changing image on my frame. The imagepath is always the same, but the image will be getting overwritten every 10 seconds from another program.
The problem is that the image is not changing when I overwrite it with another image with the same name. So in my understanding: Compiler looks every look in the path and gets the image -> when the image changed it will be changed on the frame!
I hope you understand my problem and somebody could help me.
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GUI extends JFrame{
public ImageIcon imageBar;
public JLabel labelimage1;
private JLabel labelimage2;
private JLabel bar1 = new JLabel();
private JLabel bar2 = new JLabel();
private JLabel bar3 = new JLabel();
private JLabel bar4 = new JLabel();
private JLabel bar5 = new JLabel();
private JButton buttonBar1 = new JButton("1");
private JButton buttonBar2 = new JButton("2");
private JButton buttonBar3 = new JButton("3");
private JButton buttonBar4 = new JButton("4");
private JButton buttonBar5 = new JButton("5");
private JPanel panel1 = new JPanel();
private JPanel panel2 = new JPanel();
private JPanel panel3 = new JPanel();
private JFrame window = new JFrame("Interface");
public GUI(){
//set the layouts
panel1.setLayout(new GridLayout(1, 2));
panel2.setLayout(new GridLayout(2, 1));
panel3.setLayout(new GridLayout(2, 5));
//place Panel2 and Panel3 in the window
panel1.add(panel2);
panel1.add(panel3);
//----Panel2
//refreshImage();
//----Panel3
panel3.add(buttonBar1); //add the bars 1-5 on panel3
panel3.add(buttonBar2);
panel3.add(buttonBar3);
panel3.add(buttonBar4);
panel3.add(buttonBar5);
//configure the frame
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
window.setSize(800, 400);
window.getContentPane().add(panel1);
}
public void refreshImage() {
panel2.removeAll(); //delete the old panel
//panel2.repaint();
//panel2.revalidate()
DrawImage pan = new DrawImage();
panel2.add(pan);
panel2.add(labelimage2);
}
}
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class DrawImage extends JPanel implements ActionListener{
private ImageIcon image;
public DrawImage(){
image = new ImageIcon("C:\\Users\\usuario\\Desktop\\image.png");
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
image.paintIcon(this, g, 50, 50);
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}
import java.io.File;
public class Main {
public static void main(String[] args) {
GUI Interface = new GUI();
while(true)
{
Interface.refreshImage();
try {
Thread.sleep(5000); //wait for 5000ms
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Thank you very much!
The likely cause is Java is caching the image in memory, associated with the source name. So rather then trying to reload the image again, Java simply returns the cached version.
You could use ImageIcon#getImage#flush to force Java to reconstruct the image
Problems
You are calling refreshImage from a Thread other then the Event Dispatching Thread, this could cause issues with the updating of the components and cause rendering artifacts
You are forcefully removing the DrawImage pane and adding a new instance, rather the trying to reload the image
You're calling repaint within the paintComponent method, don't do this...
You should consider using a Swing Timer, which will allow you to schedule a regular update and be notified within the context of the Event Dispatching Thread.
You could provide a simple refresh method which flushes the current ImageIcon and schedule a repaint of the panel...or you could just use a JLabel and save your self the time
An example of Image#flush
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SlideShow {
public ImageIcon imageBar;
public static void main(String[] args) {
new SlideShow();
}
public SlideShow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DrawImage());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DrawImage extends JPanel {
private ImageIcon image;
public DrawImage() {
image = new ImageIcon("D:\\thumbs\\image.png");
Timer timer = new Timer(5000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
refresh();
}
});
timer.start();
}
public void refresh() {
image.getImage().flush();
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image.getImage(), 0, 0, this);
}
}
}
The problem with this, is because the image data is loaded in a background thread, it won't may no be available when the component is first repainted, which could make the component appear to flicker.
A better approach would be to use ImageIO.read, which will ensure that the image is fully loaded before the method returns, the draw back here is that could cause the application to "pause" momentary as the image is loaded, personally, I'd use the refresh method to stop the the Timer (or set the Timer to non-repeating), start a background Thread to load the image (using ImageIO.read) call repaint (which is thread safe) and restart the Timer...
Your while (true) loop risks typing up the Swing event thread locking your program. If it doesn't do that, then you risk unpredictable threading issues by making Swing calls off of the event Thread. These problems can be solved easily by your using a Swing Timer not a while true loop to do your swapping.
Rather than removing and adding components, why not simply display images as ImageIcons within a single non-swapped JLabel.
To swap images here, simply call setIcon(...) on the JLabel.
For an example of using a Swing Timer to swap images, please check out my answer to a similar question here.
For example:
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
public class TimerImageSwapper {
public static final String[] IMAGE_URLS = {
"http://imaging.nikon.com/lineup/dslr/d7000/img/sample/img_01.png",
"http://imaging.nikon.com/lineup/dslr/d7000/img/sample/img_02.png",
"http://imaging.nikon.com/lineup/dslr/d7000/img/sample/img_04.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_08.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_05.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_01.png",
"http://imaging.nikon.com/lineup/dslr/d3200/img/sample/img_06.png" };
private ImageIcon[] icons = new ImageIcon[IMAGE_URLS.length];
private JLabel mainLabel = new JLabel();
private int iconIndex = 0;;
public TimerImageSwapper(int timerDelay) throws IOException {
for (int i = 0; i < icons.length; i++) {
URL imgUrl = new URL(IMAGE_URLS[i]);
BufferedImage image = ImageIO.read(imgUrl);
icons[i] = new ImageIcon(image);
}
mainLabel.setIcon(icons[iconIndex]);
new Timer(timerDelay, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
iconIndex++;
iconIndex %= IMAGE_URLS.length;
mainLabel.setIcon(icons[iconIndex]);
}
}).start();
}
public Component getMainComponent() {
return mainLabel;
}
private static void createAndShowGui() {
TimerImageSwapper timerImageSwapper;
try {
timerImageSwapper = new TimerImageSwapper(5 * 1000);
JFrame frame = new JFrame("Timer Image Swapper");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(timerImageSwapper.getMainComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Switching colors in a GUI

ok so i am trying to make a small java paint program but i am having trouble trying to get my buttons to work. I was able to get one color when i instantiated the MyPanel class, but i changed it around in an attempt to make use of my buttons. I basically have it setup to where each button activates a certain constructor in the MyPanel class and each constructor activates the appropriate methods to change the colors so I can draw. Im really new to programming so any advice you guys could give me would be much appreciated. I also have an extra class that is instantiated in the MyPanel class which i didnt bother putting in because i know the problem isnt in there. All the Red class does is set the color
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseMotionAdapter;
public class Driver
{
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable()
{
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
SwingUtilities.isEventDispatchThread();
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton red = new JButton("red");
JButton blue = new JButton("blue");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.setVisible(true);
frame.pack();
frame.setSize(1000,1000);
panel.add(red);
panel.add(blue);
blue.addActionListener( new Action() );
red.addActionListener( new Action() );
}
}//end driver class
public class Action implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
MyPanel d = new MyPanel();
}
}//end Action
public class MyPanel extends JPanel
{
private int xCoord = 50;
private int yCoord = 50;
private int squareW = 20;
private int squareH = 20;
Red red = new Red();
public MyPanel()
{
setBorder(BorderFactory.createLineBorder(Color.yellow));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
moveSquarer(e.getX(),e.getY());
}
});
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
moveSquarer(e.getX(),e.getY());
}
});
}
private void moveSquare(int x, int y)
{
if ((xCoord != x) || (yCoord!= y)) {
repaint(xCoord,yCoord,squareW+1,squareH+1);
red.setX(x);
red.setY(y);
repaint(red.getX(),red.getY(),red.getWidth()+1,red.getLength()+1);
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("hi",10,20);
red.paintSquare(g);
} //end MyPanel
I basically have it setup to where each button activates a certain
constructor in the MyPanel class and each constructor activates the
appropriate methods to change the colors so I can draw.
I can't see it since your ActionListener is the same for both buttons:
private static void createAndShowGUI() {
...
blue.addActionListener( new Action() );
red.addActionListener( new Action() );
...
}
public class Action implements ActionListener {
#Override
public void actionPerformed( ActionEvent e ) {
MyPanel d = new MyPanel();
}
}
This method doesn't even add this new panel to the frame so it will never be visible.
Also what is this object?
Red red = new Red();
Suggested approach
You may follow this suggested tips to achieve your goal:
Provide MyClass with a method to set the desired color.
Add an instance of this panel (or many as needed) to the frame when you initialize your GUI. Note: this/these may be added dinamically but you need to follow the hints about adding components to a displayed container described here
Use action listener to set the panel color as you whish.
For instance:
public class MyPanel extends JPanel {
private Color color = Color.red;
// this color should be used within paintComponent() method
public void setColor(Color newColor) {
color = newColor;
repaint();
}
...
}

I'm trying to draw a filled rectangle over an imageIcon using the coordinates of the image and the rectangle appears off

Eventually after I work out this small detail it will receive a building and room number to outline said building and room number so it is easy to locate but I can't get the rectangle to draw even close to acurately over a single room.
package programSTLApp;
/*
Program to request the classroom no. in STLCC and Display the location of
that classroom.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class STLApp extends JFrame
{
private JLabel imageLabel;
private JButton button;
private JPanel imagePanel;
private JPanel buttonPanel;
public STLApp()
{
super("My STLCC Class Locator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
buildImagePanel();
buildButtonPanel();
add(imagePanel, BorderLayout.CENTER);
add(buttonPanel,BorderLayout.SOUTH);
pack();
setVisible(true);
}
private void buildImagePanel()
{
imagePanel = new JPanel();
imageLabel = new JLabel("Click the button to see the drawing indicating "
+ "the location of your class");
imagePanel.add(imageLabel);
}
private void buildButtonPanel()
{
buttonPanel = new JPanel();
button = new JButton("Get Image");
button.addActionListener(new ButtonListener());
buttonPanel.add(button);
}
private class ButtonListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent e)
{
ImageIcon SiteLayoutFV = new ImageIcon("D:\\B120.jpg");
imageLabel.setIcon(SiteLayoutFV);
imageLabel.setText(null);
pack();
}
}
public void paint(Graphics g)
{
super.paint(g);
g.setColor(Color.RED);
g.fillRect(55,740,164,815);
}
public static void main(String[] args)
{
new STLApp();
}
}
As has already being pointed out, top level containers ain't a studiable class for performing custom painting, there is just to much going with these containers to make it easy to paint to.
Instead, create yourself a custom component, extending from something like JPanel, and override it's paintComponent method.
Once you have the floor pane rendered, you can render you custom elements over the top of it.
How you store this information is up to you, but basically, you need some kind of mapping that would allow you to take the floor/room and get the Shape that should be rendered.
Because the floor map might float (it may not always be rendered at 0x0 for example), you need to be able to translate the coordinates so that the Shape will always match.
Take a look at...
Performing Custom Painting
2D Graphics
For more details
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.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FloorPlan {
public static void main(String[] args) {
new FloorPlan();
}
public FloorPlan() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage floorPlan;
private Rectangle myOffice = new Rectangle(150, 50, 32, 27);
public TestPane() {
try {
floorPlan = ImageIO.read(new File("floorPlan.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return floorPlan == null ? new Dimension(200, 200) : new Dimension(floorPlan.getWidth(), floorPlan.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (floorPlan != null) {
int x = (getWidth() - floorPlan.getWidth()) / 2;
int y = (getHeight() - floorPlan.getHeight()) / 2;
g2d.drawImage(floorPlan, x, y, this);
g2d.setColor(Color.RED);
g2d.translate(x, y);
g2d.draw(myOffice);
}
g2d.dispose();
}
}
}

Categories

Resources