How do I clear my Jpanel but keep the grid lines? - java

I'm drawing lines on a JPanel using a paint component and graphics 2D, but the background of the JPanel is set to a grid which is drawn when the user enters some dimensions. How do I clear the lines drawn on the JPanel when a button is clicked but regenerate a fresh panel again with the grid lines drawn? With the action event method for the clear button, I've tried using repaint(), removeAll() and creating a new instance of the JPanel but none of that seems to work.
Here is the code for the class with the main Panel and button functions:
package floorplan;
/**
*
* #author xodkx
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
public class FloorPlan extends JFrame
{
private JPanel backPanel = new JPanel();
private JPanel toolsPanel = new JPanel();
private JFrame chooseFurniture;
private JFrame chooseFixture;
private JFrame chooseFramework;
private JButton furnitureButton = new JButton();
private JButton fixturesButton = new JButton();
private JButton frameworkButton = new JButton();
private JButton deleteButton = new JButton();
private JButton saveButton = new JButton();
private JButton clearButton = new JButton();
private JButton closeButton = new JButton();
private JRadioButton wall = new JRadioButton("Wall");
private JRadioButton door = new JRadioButton("Door");
private JRadioButton window = new JRadioButton("Window");
Floor floor = new Floor();
public FloorPlan()
{
super("Floor Plan Generator");
createWindow();
buttonFunctions();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
private void createWindow()
{
backPanel.setLayout(new BorderLayout());
backPanel.setBorder(BorderFactory.createEmptyBorder(200, 200, 200, 200));
GridLayout panelLayout = new GridLayout();
frameworkButton.setText("Framework");
fixturesButton.setText("Fixtures");
furnitureButton.setText("Furniture");
deleteButton.setText("Delete");
saveButton.setText("Save");
clearButton.setText("Clear");
add(backPanel, BorderLayout.CENTER);
backPanel.add(toolsPanel, BorderLayout.NORTH);
backPanel.add(floor, BorderLayout.CENTER);
backPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
toolsPanel.add(frameworkButton);
toolsPanel.add(fixturesButton);
toolsPanel.add(furnitureButton);
toolsPanel.add(deleteButton);
toolsPanel.add(saveButton);
toolsPanel.add(clearButton);
add(backPanel);
}
private void buttonFunctions()
{
frameworkButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent e)
{
chooseFramework = new JFrame("Pick A Framework");
chooseFramework.setSize(250,250);
chooseFramework.setLayout(new GridLayout(4,1));
chooseFramework.add(wall);
chooseFramework.add(door);
chooseFramework.add(window);
chooseFramework.add(closeButton);
closeButton.setText("Close");
wall.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
floor.setFramework(Framework.WALL);
}});
door.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
floor.setColor(Color.RED);
floor.setFramework(Framework.DOOR);
}});
window.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
floor.setColor(Color.BLUE);
floor.setFramework(Framework.WALL);
}});
closeButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
chooseFramework.setVisible(false);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
chooseFramework.setVisible(true);
}
});
furnitureButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent e)
{
chooseFurniture = new JFrame("Pick Furniture to add");
chooseFurniture.setSize(250,250);
chooseFurniture.setLayout(new GridLayout(4,1));
chooseFurniture.add(closeButton);
closeButton.setText("Close");
closeButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
chooseFurniture.setVisible(false);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
chooseFurniture.setVisible(true);
}
});
fixturesButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent e)
{
chooseFixture = new JFrame("Pick Furniture to add");
chooseFixture.setSize(250,250);
chooseFixture.setLayout(new GridLayout(4,1));
chooseFixture.add(closeButton);
closeButton.setText("Close");
closeButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
chooseFixture.setVisible(false);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
chooseFixture.setVisible(true);
}
});
**clearButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent e)
{
**//THIS IS WHERE I WANT TO CLEAR THE JPANEL WHEN THIS BUTTON IS CLICKED**
}
});**
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
FloorPlan floorPlan = new FloorPlan();
}
});
}
}
Here is the class that does all the graphics stuff and draws onto the JPanel
package floorplan;
/**
*
* #author xodkx
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.awt.event.MouseListener;
public class Floor extends JPanel implements MouseListener, MouseMotionListener
{
private static final int WIDTH = Integer.parseInt(JOptionPane.showInputDialog("Please
enter the width of your room"));
private static final int LENGTH = Integer.parseInt(JOptionPane.showInputDialog("Please
enter the width of your room"));
private static final Color BACKGROUND = Color.WHITE;
private static final Color INITIAL_COLOUR = Color.BLACK;
private static final Framework INITIAL_FRAMEWORK = Framework.WALL;
private MouseState state = MouseState.IDLE;
private Framework frameworkType = INITIAL_FRAMEWORK;
private Color colour = INITIAL_COLOUR;
private Point start = null;
private Point end = null;
private Point startpt = null;
private Point endpt = null;
private BufferedImage bufImage = null;
public Floor()
{
setPreferredSize(new Dimension(LENGTH,WIDTH));
setBackground(Color.white);
setBorder(BorderFactory.createLineBorder (Color.black, 5));
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void setColor(Color color)
{
colour = color;
}
public void setFramework(Framework framework)
{
frameworkType = framework;
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if(bufImage == null)
{
int h = this.getHeight();
int w = this.getWidth();
bufImage = (BufferedImage)this.createImage(h,w);
Graphics2D gc = bufImage.createGraphics();
gc.setColor(BACKGROUND);
gc.fillRect(0, 0, w, h);
}
g2.drawImage(bufImage,null,0,0);
drawGrid(g2);
if(state == MouseState.DRAGGING)
{
createComponent(g2);
}
}
public void drawGrid(Graphics g2)
{
int gridDivisions = 20;
int divisionSize = WIDTH/gridDivisions;
int grid = WIDTH*LENGTH;
g2.setColor(Color.lightGray);
for(int i=1; i<grid; i++)
{
int x = i * divisionSize;
g2.drawLine(x,0,x,getSize().height);
}
for(int i=1; i<grid; i++)
{
int y = i*divisionSize;
g2.drawLine(0,y,getSize().width,y);
}
}
public void createComponent(Graphics2D g2)
{
g2.setColor(colour);
switch (frameworkType)
{
case WALL:
g2.setStroke(new BasicStroke(5));
g2.drawLine(start.x, start.y, end.x,end.y);
break;
case DOOR:
g2.setStroke(new BasicStroke(5));
g2.drawLine(start.x, start.y, end.x,end.y);
break;
case WINDOW:
g2.setStroke(new BasicStroke(5));
g2.drawLine(start.x, start.y, end.x,end.y);
break;
default:
g2.drawString("test", 10, 20);
break;
}
}
#Override
public void mousePressed(MouseEvent e)
{
state = MouseState.DRAGGING;
start = e.getPoint();
end = start;
}
#Override
public void mouseDragged(MouseEvent e)
{
state = MouseState.DRAGGING;
end = e.getPoint();
this.repaint();
}
#Override
public void mouseReleased(MouseEvent e)
{
end = e.getPoint();
if(state == MouseState.DRAGGING)
{
state = MouseState.IDLE;
createComponent(bufImage.createGraphics());
this.repaint();
}
}
#Override
public void mouseClicked(MouseEvent e)
{
}
#Override
public void mouseEntered(MouseEvent e)
{
}
#Override
public void mouseExited(MouseEvent e)
{
}
#Override
public void mouseMoved(MouseEvent e)
{
}
}

It is not clear exactly how do you want to incorporate the logic of displaying the grid. Here is an example how to toggle it just to give you the idea. In Floor class add boolean flag that controls whether the grid is displayed or not. Then in Floor.paintComponent() draw grid based on the value of this boolean flag. Changing the flag's value should trigger a repaint. Then, change the value of this flag from FloorPlan class, in response to an action or some other program logic. Here is a simple implementation that toggles grid when clear button is clicked :
Floor class:
private boolean displayGrid = true;
public boolean isDisplayGrid() {
return displayGrid;
}
public void setDisplayGrid(boolean displayGrid) {
this.displayGrid = displayGrid;
repaint();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
...
if (displayGrid)
drawGrid(g2);
}
FloorPlan class:
clearButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
floor.setDisplayGrid(!floor.isDisplayGrid());
}
});
EDIT:
Seems that I totally misinterpreted your question. If I understand correctly you want to clear the drawings upon a button click. Looks like all the drawings are done on the bufImage in the Floor class. Simply reset this image, ie:
Floor class:
public void clear() {
bufImage.flush();
bufImage = null;
repaint();
}
FloorPlan class:
clearButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
floor.clear();
}
});

You could use a for loop with panel.remove the buttons (instead of panel.add)

Related

How to let user draw inside a canvas and save image afterwards?

I am trying to implement a free hand drawing Java applet which allows user to draw something in canvas (canvas is not the priority, it could be anything else as long I can save the image after (need to save it, because I have to display it later in a different place after pressing a button, any other solutions are welcome)). I found a code, which allows me to draw, but now I am having a trouble with drawing inside the canvas... And I have already spent few days with no results on that. Here is the code I have by now and a description below it:
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.*;
import java.applet.*;
public class paintMozApplet extends Applet implements ActionListener
{
int xPressed,yPressed;
int xReleased,yReleased;
int xDragged,yDragged;
private GridLayout gL;
private JPanel buttons;
private JPanel panel;
private Button clear, createMoz;
private Label result_here;
private javax.swing.JPanel drawing;
private JPanel moz;
private Canvas canvas;
private draw draw;
public paintMozApplet()
{
draw = new draw();
gL = new GridLayout(1, 0);
buttons = new JPanel();
drawing = new JPanel();
moz = new JPanel();
canvas = new Canvas();
clear = new Button("clear");
createMoz = new Button("Create Moz");
buttons.add(clear);
buttons.add(createMoz);
result_here = new Label("Result here!");
moz.add(result_here);
drawing.add(canvas);
clear.addActionListener(this);
//canvas.add(draw);
//canvas.addMouseMotionListener(this);
canvas.setPreferredSize(new Dimension(200, 200));
canvas.setBackground(Color.green);
add(drawing);
add(buttons);
add(moz);
add(draw);
setPreferredSize(new Dimension(1000, 1000));
setSize(1000, 1000);
setLayout(gL);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==clear)
{
//setOpaque(false);
repaint();
}
}
}
class draw extends JFrame implements MouseListener, MouseMotionListener, ActionListener {
int xPressed,yPressed;
int xReleased,yReleased;
int xDragged,yDragged;
private JButton clear;
public draw()
{
setPreferredSize(new Dimension(1200, 500));
setBounds(0, 0, 480, 500);
clear=new JButton("CLEAR");
add(clear);
clear.setBounds(540, 5, 100, 25);
clear.addActionListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
protected void paintComponent(Graphics g)
{
g.drawLine(xPressed,yPressed,xDragged,yDragged);
xPressed=xDragged;
yPressed=yDragged;
}
#Override
public void mouseDragged(MouseEvent arg0) {
Graphics g = getGraphics();
g.drawLine(xPressed, yPressed, arg0.getX(), arg0.getY());
xDragged = arg0.getX();
yDragged = arg0.getY();
repaint();
}
#Override
public void mouseMoved(MouseEvent arg0) {
}
#Override
public void mouseClicked(MouseEvent arg0) {
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
xPressed = arg0.getX();
yPressed = arg0.getY();
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
So my idea is to create two classes where one is used to draw and other to create place where to draw and everything else. I have tried lots of things and now I am here and cant figure out, how to cal the draw class on my canvas so it will draw only there. Before I had everything in one class and called mouse events on my canvas. Result was that it drawed only when I clicked on canvas, but the actual drawing went also out of canvas if I did not let go of my mouse and dragged it out of canvas. Also it did not draw in canvas, but on the background of applet, at least it looked like that.
I really hope I explained my self understanding and I am sure, that this can be solved easily since there are lots of solutions online but I can't seem to find one that would work as I intend.
I suggest starting with this approach based around a BufferedImage as the painting surface..
import java.awt.*;
import java.awt.RenderingHints.Key;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
public class BasicPaint {
/** Reference to the original image. */
private BufferedImage originalImage;
/** Image used to make changes. */
private BufferedImage canvasImage;
/** The main GUI that might be added to a frame or applet. */
private JPanel gui;
/** The color to use when calling clear, text or other
* drawing functionality. */
private Color color = Color.WHITE;
/** General user messages. */
private JLabel output = new JLabel("You DooDoodle!");
private BufferedImage colorSample = new BufferedImage(
16,16,BufferedImage.TYPE_INT_RGB);
private JLabel imageLabel;
private int activeTool;
public static final int SELECTION_TOOL = 0;
public static final int DRAW_TOOL = 1;
public static final int TEXT_TOOL = 2;
private Point selectionStart;
private Rectangle selection;
private boolean dirty = false;
private Stroke stroke = new BasicStroke(
3,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND,1.7f);
private RenderingHints renderingHints;
public JComponent getGui() {
if (gui==null) {
Map<Key, Object> hintsMap = new HashMap<RenderingHints.Key,Object>();
hintsMap.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
hintsMap.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
hintsMap.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
renderingHints = new RenderingHints(hintsMap);
setImage(new BufferedImage(320,240,BufferedImage.TYPE_INT_RGB));
gui = new JPanel(new BorderLayout(4,4));
gui.setBorder(new EmptyBorder(5,3,5,3));
JPanel imageView = new JPanel(new GridBagLayout());
imageView.setPreferredSize(new Dimension(480,320));
imageLabel = new JLabel(new ImageIcon(canvasImage));
JScrollPane imageScroll = new JScrollPane(imageView);
imageView.add(imageLabel);
imageLabel.addMouseMotionListener(new ImageMouseMotionListener());
imageLabel.addMouseListener(new ImageMouseListener());
gui.add(imageScroll,BorderLayout.CENTER);
JToolBar tb = new JToolBar();
tb.setFloatable(false);
JButton colorButton = new JButton("Color");
colorButton.setMnemonic('o');
colorButton.setToolTipText("Choose a Color");
ActionListener colorListener = new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Color c = JColorChooser.showDialog(
gui, "Choose a color", color);
if (c!=null) {
setColor(c);
}
}
};
colorButton.addActionListener(colorListener);
colorButton.setIcon(new ImageIcon(colorSample));
tb.add(colorButton);
setColor(color);
final SpinnerNumberModel strokeModel =
new SpinnerNumberModel(3,1,16,1);
JSpinner strokeSize = new JSpinner(strokeModel);
ChangeListener strokeListener = new ChangeListener() {
#Override
public void stateChanged(ChangeEvent arg0) {
Object o = strokeModel.getValue();
Integer i = (Integer)o;
stroke = new BasicStroke(
i.intValue(),
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND,
1.7f);
}
};
strokeSize.addChangeListener(strokeListener);
strokeSize.setMaximumSize(strokeSize.getPreferredSize());
JLabel strokeLabel = new JLabel("Stroke");
strokeLabel.setLabelFor(strokeSize);
strokeLabel.setDisplayedMnemonic('t');
tb.add(strokeLabel);
tb.add(strokeSize);
tb.addSeparator();
ActionListener clearListener = new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int result = JOptionPane.OK_OPTION;
if (dirty) {
result = JOptionPane.showConfirmDialog(
gui, "Erase the current painting?");
}
if (result==JOptionPane.OK_OPTION) {
clear(canvasImage);
}
}
};
JButton clearButton = new JButton("Clear");
tb.add(clearButton);
clearButton.addActionListener(clearListener);
gui.add(tb, BorderLayout.PAGE_START);
JToolBar tools = new JToolBar(JToolBar.VERTICAL);
tools.setFloatable(false);
JButton crop = new JButton("Crop");
final JRadioButton select = new JRadioButton("Select", true);
final JRadioButton draw = new JRadioButton("Draw");
final JRadioButton text = new JRadioButton("Text");
tools.add(crop);
tools.add(select);
tools.add(draw);
tools.add(text);
ButtonGroup bg = new ButtonGroup();
bg.add(select);
bg.add(text);
bg.add(draw);
ActionListener toolGroupListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource()==select) {
activeTool = SELECTION_TOOL;
} else if (ae.getSource()==draw) {
activeTool = DRAW_TOOL;
} else if (ae.getSource()==text) {
activeTool = TEXT_TOOL;
}
}
};
select.addActionListener(toolGroupListener);
draw.addActionListener(toolGroupListener);
text.addActionListener(toolGroupListener);
gui.add(tools, BorderLayout.LINE_END);
gui.add(output,BorderLayout.PAGE_END);
clear(colorSample);
clear(canvasImage);
}
return gui;
}
/** Clears the entire image area by painting it with the current color. */
public void clear(BufferedImage bi) {
Graphics2D g = bi.createGraphics();
g.setRenderingHints(renderingHints);
g.setColor(color);
g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
g.dispose();
imageLabel.repaint();
}
public void setImage(BufferedImage image) {
this.originalImage = image;
int w = image.getWidth();
int h = image.getHeight();
canvasImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
Graphics2D g = this.canvasImage.createGraphics();
g.setRenderingHints(renderingHints);
g.drawImage(image, 0, 0, gui);
g.dispose();
selection = new Rectangle(0,0,w,h);
if (this.imageLabel!=null) {
imageLabel.setIcon(new ImageIcon(canvasImage));
this.imageLabel.repaint();
}
if (gui!=null) {
gui.invalidate();
}
}
/** Set the current painting color and refresh any elements needed. */
public void setColor(Color color) {
this.color = color;
clear(colorSample);
}
private JMenu getFileMenu(boolean webstart){
JMenu file = new JMenu("File");
file.setMnemonic('f');
JMenuItem newImageItem = new JMenuItem("New");
newImageItem.setMnemonic('n');
ActionListener newImage = new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
BufferedImage bi = new BufferedImage(
360, 300, BufferedImage.TYPE_INT_ARGB);
clear(bi);
setImage(bi);
}
};
newImageItem.addActionListener(newImage);
file.add(newImageItem);
if (webstart) {
//TODO Add open/save functionality using JNLP API
} else {
//TODO Add save functionality using J2SE API
file.addSeparator();
ActionListener openListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if (!dirty) {
JFileChooser ch = getFileChooser();
int result = ch.showOpenDialog(gui);
if (result==JFileChooser.APPROVE_OPTION ) {
try {
BufferedImage bi = ImageIO.read(
ch.getSelectedFile());
setImage(bi);
} catch (IOException e) {
showError(e);
e.printStackTrace();
}
}
} else {
// TODO
JOptionPane.showMessageDialog(
gui, "TODO - prompt save image..");
}
}
};
JMenuItem openItem = new JMenuItem("Open");
openItem.setMnemonic('o');
openItem.addActionListener(openListener);
file.add(openItem);
ActionListener saveListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser ch = getFileChooser();
int result = ch.showSaveDialog(gui);
if (result==JFileChooser.APPROVE_OPTION ) {
try {
File f = ch.getSelectedFile();
ImageIO.write(BasicPaint.this.canvasImage, "png", f);
BasicPaint.this.originalImage = BasicPaint.this.canvasImage;
dirty = false;
} catch (IOException ioe) {
showError(ioe);
ioe.printStackTrace();
}
}
}
};
JMenuItem saveItem = new JMenuItem("Save");
saveItem.addActionListener(saveListener);
saveItem.setMnemonic('s');
file.add(saveItem);
}
if (canExit()) {
ActionListener exit = new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
System.exit(0);
}
};
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.setMnemonic('x');
file.addSeparator();
exitItem.addActionListener(exit);
file.add(exitItem);
}
return file;
}
private void showError(Throwable t) {
JOptionPane.showMessageDialog(
gui,
t.getMessage(),
t.toString(),
JOptionPane.ERROR_MESSAGE);
}
JFileChooser chooser = null;
public JFileChooser getFileChooser() {
if (chooser==null) {
chooser = new JFileChooser();
FileFilter ff = new FileNameExtensionFilter("Image files", ImageIO.getReaderFileSuffixes());
chooser.setFileFilter(ff);
}
return chooser;
}
public boolean canExit() {
boolean canExit = false;
SecurityManager sm = System.getSecurityManager();
if (sm==null) {
canExit = true;
} else {
try {
sm.checkExit(0);
canExit = true;
} catch(Exception stayFalse) {
}
}
return canExit;
}
public JMenuBar getMenuBar(boolean webstart){
JMenuBar mb = new JMenuBar();
mb.add(this.getFileMenu(webstart));
return mb;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
// use default
}
BasicPaint bp = new BasicPaint();
JFrame f = new JFrame("DooDoodle!");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(bp.getGui());
f.setJMenuBar(bp.getMenuBar(false));
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
public void text(Point point) {
String text = JOptionPane.showInputDialog(gui, "Text to add", "Text");
if (text!=null) {
Graphics2D g = this.canvasImage.createGraphics();
g.setRenderingHints(renderingHints);
g.setColor(this.color);
g.setStroke(stroke);
int n = 0;
g.drawString(text,point.x,point.y);
g.dispose();
this.imageLabel.repaint();
}
}
public void draw(Point point) {
Graphics2D g = this.canvasImage.createGraphics();
g.setRenderingHints(renderingHints);
g.setColor(this.color);
g.setStroke(stroke);
int n = 0;
g.drawLine(point.x, point.y, point.x+n, point.y+n);
g.dispose();
this.imageLabel.repaint();
}
class ImageMouseListener extends MouseAdapter {
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
if (activeTool==BasicPaint.SELECTION_TOOL) {
selectionStart = arg0.getPoint();
} else if (activeTool==BasicPaint.DRAW_TOOL) {
// TODO
draw(arg0.getPoint());
} else if (activeTool==BasicPaint.TEXT_TOOL) {
// TODO
text(arg0.getPoint());
} else {
JOptionPane.showMessageDialog(
gui,
"Application error. :(",
"Error!",
JOptionPane.ERROR_MESSAGE);
}
}
#Override
public void mouseReleased(MouseEvent arg0) {
if (activeTool==BasicPaint.SELECTION_TOOL) {
selection = new Rectangle(
selectionStart.x,
selectionStart.y,
arg0.getPoint().x,
arg0.getPoint().y);
}
}
}
class ImageMouseMotionListener implements MouseMotionListener {
#Override
public void mouseDragged(MouseEvent arg0) {
reportPositionAndColor(arg0);
if (activeTool==BasicPaint.SELECTION_TOOL) {
selection = new Rectangle(
selectionStart.x,
selectionStart.y,
arg0.getPoint().x-selectionStart.x,
arg0.getPoint().y-selectionStart.y);
} else if (activeTool==BasicPaint.DRAW_TOOL) {
draw(arg0.getPoint());
}
}
#Override
public void mouseMoved(MouseEvent arg0) {
reportPositionAndColor(arg0);
}
}
private void reportPositionAndColor(MouseEvent me) {
String text = "";
if (activeTool==BasicPaint.SELECTION_TOOL) {
text += "Selection (X,Y:WxH): " +
(int)selection.getX() +
"," +
(int)selection.getY() +
":" +
(int)selection.getWidth() +
"x" +
(int)selection.getHeight();
} else {
text += "X,Y: " + (me.getPoint().x+1) + "," + (me.getPoint().y+1);
}
output.setText(text);
}
}
This source is very patchy.
It has many parts with // TODO
A dirty attribute is declared but never used in any meaningful way. ..
It is just something I hacked together today and thought should be shown before it hit the posting limit.
Oh, and don't go looking for any 'OO design' since I did not put any in. If there is any, it is only by accident. This code is intended to demonstrate what is possible and how to start doing it.

How to change the background color of a JFrame dynamically?

Hello i was wondering of how to change the background color of a JFrame dynamically as in this Website when you click on the button Ok, Let's Go and then select any option, the background change dynamically, i would like to do it, but using a JFrame. I was thinking on create a cicle to do it. If someone do knows how to do it, i'll be thankful
This is what i want:
Could you please make an example?
Below is an example switching from blue to green and green to blue. There's bug with the first click to green. And it's probably not the most robust code, but It's just an example that I'm too lazy to improve on right now. You can play with it
import java.awt.Color;
import java.awt.Dimension;
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.SwingUtilities;
import javax.swing.Timer;
public class ChangeColor {
public ChangeColor() {
JFrame frame = new JFrame();
frame.add(new ColorPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class ColorPanel extends JPanel {
private static final int DELAY = 30;
private static final int INCREMENT = 5;
private Color currentColor = Color.BLUE;
boolean isBlue = true;
boolean isGreen = false;
private int r,g,b;
private Timer timer = null;
private JButton greenButton = null;
private JButton blueButton = null;
public ColorPanel() {
r = 0; g = 0; b = 255;
greenButton = createGreenButton();
blueButton = createBlueButton();
timer = new Timer(DELAY, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (isBlue) {
if (b == 0) {
stopTimer();
enableButtons();
} else {
blueToGreen();
setColor(new Color(r, b, g));
}
}
if (isGreen) {
if (g == 0) {
stopTimer();
enableButtons();
} else {
greenToBlue();
setColor(new Color(r, b, g));
}
}
repaint();
}
});
add(blueButton);
add(greenButton);
}
public JButton createBlueButton() {
JButton button = new JButton("BLUE");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (currentColor != new Color(0, 255, 0)) {
System.out.println("turn blue");
isBlue = true;
isGreen = false;
diableButtons();
startTimer();
}
}
});
return button;
}
public void diableButtons() {
blueButton.setEnabled(false);
greenButton.setEnabled(false);
}
public void enableButtons() {
blueButton.setEnabled(true);
greenButton.setEnabled(true);
}
public JButton createGreenButton() {
JButton button = new JButton("GREEN");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (currentColor != new Color(0, 0, 255)) {
System.out.println("turn green");
isGreen = true;
isBlue = false;
diableButtons();
startTimer();
}
}
});
return button;
}
private void blueToGreen() {
b -= INCREMENT;
g += INCREMENT;
}
private void greenToBlue() {
g -= INCREMENT;
b += INCREMENT;
}
public void setColor(Color color) {
this.currentColor = color;
}
public void startTimer() {
timer.start();
}
public void stopTimer() {
timer.stop();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(currentColor);
g.fillRect(0, 0, getWidth(), getHeight());
}
#Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new ChangeColor();
}
});
}
}
YourJFrame.getContentPane().setBackground(Color.colorName);
Where "YourJFrame" is the name of your component and "colorName" is the name of one of the colors available in the Color class.
Add this to the actionListeners of your buttons
JFrame.getContentPane().setBackground(Color.colorName);
And change the colours at will.

Press and Drag in One Click?

I have a program where I am creating a JLabel on a click and then dragging that to another portion of the interface.
What I want is to click somewhere in the JPanel, have it drop a JLabel there, and then drag another JLabel all in the same click.
I am able to do this, but it takes multiple clicks. Can I do it in one click?
To illustrate what I mean, I created this sample program:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DragTest extends JFrame implements MouseMotionListener,
MouseListener {
private JPanel panel = new JPanel(null);
private JLabel dragLabel = new JLabel("drag");;
private final JWindow window = new JWindow();
public DragTest() {
this.add(panel);
panel.addMouseListener(this);
dragLabel.setFont(new Font("Serif", Font.BOLD, 48));
}
#Override
public void mouseDragged(MouseEvent me) {
dragLabel = new JLabel("drag");
dragLabel.setFont(new Font("Serif", Font.BOLD, 48));
int x = me.getPoint().x;
int y = me.getPoint().y;
window.add(dragLabel);
window.pack();
Point pt = new Point(x, y);
Component c = (Component) me.getSource();
SwingUtilities.convertPointToScreen(pt, c);
window.setLocation(pt);
window.setVisible(true);
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
JLabel dropLabel = new JLabel("drop");
panel.add(dropLabel);
dropLabel.setForeground(Color.RED);
dropLabel.setFont(new Font("Serif", Font.BOLD, 48));
dropLabel.setBounds(e.getX(), e.getY(), 100, 60);
dropLabel.addMouseMotionListener(this);
dropLabel.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
dragLabel.setVisible(false);
window.setVisible(false);
}
});
repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
public static void main(String[] args) {
DragTest frame = new DragTest();
frame.setVisible(true);
frame.setSize(600, 400);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
So the initial click creates the "drop" JLabel, and then clicking on and dragging on the "drop" JLabel will create a "drag" JLabel that follows the mouse around.
How can I do this in one click and drag?
Don't create a new JLabel in the mouseDragged method but rather use the same JLabel. For example:
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class DragTest2 extends JPanel {
private static final int PREF_W = 500;
private static final int PREF_H = 400;
private static final float LABEL_PTS = 24f;
private static final String LABEL_TEXT = "My Label";
private JLabel label = null;
public DragTest2() {
setLayout(null);
MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
addMouseListener(myMouseAdapter);
addMouseMotionListener(myMouseAdapter);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
class MyMouseAdapter extends MouseAdapter {
#Override
public void mousePressed(MouseEvent e) {
label = new JLabel(LABEL_TEXT);
label.setFont(label.getFont().deriveFont(LABEL_PTS));
Dimension labelSize = label.getPreferredSize();
label.setSize(labelSize);
int x = e.getX() - labelSize.width / 2;
int y = e.getY() - labelSize.height / 2;
label.setLocation(x , y);
add(label);
repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
if (label != null) {
Dimension labelSize = label.getPreferredSize();
int x = e.getX() - labelSize.width / 2;
int y = e.getY() - labelSize.height / 2;
label.setLocation(x , y);
repaint();
}
}
#Override
public void mouseReleased(MouseEvent e) {
if (label != null) {
Dimension labelSize = label.getPreferredSize();
int x = e.getX() - labelSize.width / 2;
int y = e.getY() - labelSize.height / 2;
label.setLocation(x , y);
repaint();
label = null;
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("DragTest2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new DragTest2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}

Changing Swing GUI Default Look and Feel in real time

Before showing the GUI, if i have a code block like this:
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("GTK+".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception ex) {}
Here for example, i am using theme GTK+ in ubunut. Other options like Nimbus etc can be used. Now once i launch the app, it loads and show this theme. But is there anyway i can change the theme in real time. Because if i change it i have to close the GUI and load it again with new theme?
Is possible change Look and Feel on Runtime by invoke SwingUtilities#updateComponentTreeUI, for example
import java.awt.event.*;
import java.awt.Color;
import java.awt.AlphaComposite;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
public class ButtonTest {
private JFrame frame;
private JButton opaqueButton1;
private JButton opaqueButton2;
private SoftJButton softButton1;
private SoftJButton softButton2;
private Timer alphaChanger;
public void createAndShowGUI() {
opaqueButton1 = new JButton("Opaque Button");
opaqueButton2 = new JButton("Opaque Button");
softButton1 = new SoftJButton("Transparent Button");
softButton2 = new SoftJButton("Transparent Button");
opaqueButton1.setBackground(Color.GREEN);
softButton1.setBackground(Color.GREEN);
frame = new JFrame();
frame.getContentPane().setLayout(new java.awt.GridLayout(2, 2, 10, 10));
frame.add(opaqueButton1);
frame.add(softButton1);
frame.add(opaqueButton2);
frame.add(softButton2);
frame.setSize(700, 300);
frame.setLocation(150, 100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
alphaChanger = new Timer(30, new ActionListener() {
private float incrementer = -.03f;
#Override
public void actionPerformed(ActionEvent e) {
float newAlpha = softButton1.getAlpha() + incrementer;
if (newAlpha < 0) {
newAlpha = 0;
incrementer = -incrementer;
} else if (newAlpha > 1f) {
newAlpha = 1f;
incrementer = -incrementer;
}
softButton1.setAlpha(newAlpha);
softButton2.setAlpha(newAlpha);
}
});
alphaChanger.start();
Timer uiChanger = new Timer(3500, new ActionListener() {
private final LookAndFeelInfo[] laf = UIManager.getInstalledLookAndFeels();
private int index = 1;
#Override
public void actionPerformed(ActionEvent e) {
try {
UIManager.setLookAndFeel(laf[index].getClassName());
SwingUtilities.updateComponentTreeUI(frame);
opaqueButton1.setText(laf[index].getClassName());
softButton1.setText(laf[index].getClassName());
} catch (Exception exc) {
exc.printStackTrace();
}
index = (index + 1) % laf.length;
}
});
uiChanger.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ButtonTest().createAndShowGUI();
}
});
}
private static class SoftJButton extends JButton {
private static final JButton lafDeterminer = new JButton();
private static final long serialVersionUID = 1L;
private boolean rectangularLAF;
private float alpha = 1f;
SoftJButton() {
this(null, null);
}
SoftJButton(String text) {
this(text, null);
}
SoftJButton(String text, Icon icon) {
super(text, icon);
setOpaque(false);
setFocusPainted(false);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
repaint();
}
#Override
public void paintComponent(java.awt.Graphics g) {
java.awt.Graphics2D g2 = (java.awt.Graphics2D) g;
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
if (rectangularLAF && isBackgroundSet()) {
Color c = getBackground();
g2.setColor(c);
g.fillRect(0, 0, getWidth(), getHeight());
}
super.paintComponent(g2);
}
#Override
public void updateUI() {
super.updateUI();
lafDeterminer.updateUI();
rectangularLAF = lafDeterminer.isOpaque();
}
}
}

Drawing transculent rectangle

I was a problem with drawing rectangle using mouse. I have solve my problem and I get results what I want. But I have a small problem. If I want to start draw rectangle when I click mouse button, text in my button change. This is small difference but I don't want see this. Here is code:
package draw;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.event.*;
public class Selection extends JPanel
implements ChangeListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final int WIDE = 640;
private static final int HIGH = 640;
private List<Node> nodes = new ArrayList<Node>();
private Point mousePt = new Point(WIDE / 2, HIGH / 2);
private Rectangle mouseRect = new Rectangle();
private boolean selecting = false;
public static void main(String[] args) throws Exception {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("GraphPanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Selection gp = new Selection();
gp.add(new JButton("Button"));
f.add(new JScrollPane(gp), BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
});
}
Selection() {
this.setPreferredSize(new Dimension(WIDE, HIGH));
this.addMouseListener(new MouseHandler());
this.addMouseMotionListener(new MouseMotionHandler());
}
#Override
public void paintComponent(Graphics g) {
g.setColor(new Color(0x00f0f0f0));
g.fillRect(0, 0, getWidth(), getHeight());
for (Node n : nodes) {
n.draw(g);
}
if (selecting) {
g.setColor(Color.BLACK
);
((Graphics2D) g).setComposite(AlphaComposite.getInstance(rule, alpha));
g.fillRect(mouseRect.x, mouseRect.y,
mouseRect.width, mouseRect.height);
g.drawRect(mouseRect.x, mouseRect.y,
mouseRect.width, mouseRect.height);
}
}
int rule = AlphaComposite.SRC_OVER;
float alpha = 0.9F;
private class MouseHandler extends MouseAdapter {
#Override
public void mouseReleased(MouseEvent e) {
selecting = false;
mouseRect.setBounds(0, 0, 0, 0);
if (e.isPopupTrigger()) {
}
e.getComponent().repaint();
}
#Override
public void mousePressed(MouseEvent e) {
mousePt = e.getPoint();
Node.selectNone(nodes);
selecting = true;
e.getComponent().repaint();
}
}
private class MouseMotionHandler extends MouseMotionAdapter {
Point delta = new Point();
#Override
public void mouseDragged(MouseEvent e) {
if (selecting) {
mouseRect.setBounds(
Math.min(mousePt.x, e.getX()),
Math.min(mousePt.y, e.getY()),
Math.abs(mousePt.x - e.getX()),
Math.abs(mousePt.y - e.getY()));
} else {
delta.setLocation(
e.getX() - mousePt.x,
e.getY() - mousePt.y);
mousePt = e.getPoint();
}
e.getComponent().repaint();
}
}
/** A Node represents a node in a graph. */
private static class Node {
private Color color;
private boolean selected = false;
private Rectangle b = new Rectangle();
/** Draw this node. */
public void draw(Graphics g) {
g.setColor(this.color);
if (selected) {
g.setColor(Color.darkGray);
g.drawRect(b.x, b.y, b.width, b.height);
}
}
/** Mark this node as slected. */
public void setSelected(boolean selected) {
this.selected = selected;
}
/** Select no nodes. */
public static void selectNone(List<Node> list) {
for (Node n : list) {
n.setSelected(false);
}
}
}
#Override
public void stateChanged(ChangeEvent arg0) {
// TODO Auto-generated method stub
}
}
I think that can be a problem with place where I implement my button. I use eclipse SDK.
Can you help me?
Change your main to this. The reason is that you are setting alpha to < 1 for the entire panel and so the button is getting lighter shade. Simply move the button out of the panel and you are set.
public static void main(String[] args) throws Exception {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("GraphPanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
JButton button = new JButton("Button");
panel.add(button, BorderLayout.PAGE_START);
Selection gp = new Selection();
panel.add(gp, BorderLayout.CENTER);
f.add(new JScrollPane(panel), BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
});
}

Categories

Resources