drawing program whiteboard not appearing? - java

Ok, so I have this assignment that tells me to make a drawing program with buttons that can draw shape operates like "Painter" drawing program on the computer. The problem is that I can't even make the white board to appear even though I follow the code of a similar java program I found on the internet.
So here's my code:
Main class:
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Toolkit;
import javax.swing.JFrame;
public class Main
{
private static final Toolkit TOOLKIT;
static
{
TOOLKIT = Toolkit.getDefaultToolkit();
}
private Main()
{
}
public static void main(final String[] argv)
{
final ShapeFrame frame;
frame = new ShapeFrame();
position(frame);
frame.init();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static void position(final JFrame frame)
{
final Dimension size;
size = calculateScreenArea(0.80f,
0.80f);
frame.setSize(size);
frame.setLocation(centreOnScreen(size));
}
/**
* the amount of center on screen
* #param size space size.
* #return the complete calculated space.
*/
public static Point centreOnScreen(final Dimension size)
{
final Dimension screenSize;
if(size == null)
{
throw new IllegalArgumentException("Size cannot be null");
}
screenSize = TOOLKIT.getScreenSize();
return (new Point((screenSize.width - size.width) / 2,
(screenSize.height - size.height) / 2));
}
/**
* method that calculating screen area.
* #param widthPercent width percentage.
* #param heightPercent height percentage.
* #return dimension the dimension.
*/
public static Dimension calculateScreenArea(final float widthPercent,
final float heightPercent)
{
final Dimension screenSize;
final Dimension area;
final int width;
final int height;
final int size;
if((widthPercent <= 0.0f) || (widthPercent > 100.0f))
{
throw new IllegalArgumentException("widthPercent cannot be " +
"<= 0 or > 100 - got: " +
widthPercent);
}
if((heightPercent <= 0.0f) || (heightPercent > 100.0f))
{
throw new IllegalArgumentException("heightPercent cannot be " +
"<= 0 or > 100 - got: " +
heightPercent);
}
screenSize = TOOLKIT.getScreenSize();
width = (int)(screenSize.width * widthPercent);
height = (int)(screenSize.height * heightPercent);
size = Math.min(width,
height);
area = new Dimension(size,
size);
return (area);
}
}
my JFrame class:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/**
* This class creates the painting program's toolbar, buttons and stuffs.
* #author Fu Han
* #version 1.0
*/
public class ShapeFrame extends JFrame implements ActionListener {
private DrawPad drawPad;
/**
* the constant string 'save'.
*/
static final private String SAVE = "Save";
/**
* the constant string 'save as'.
*/
static final private String SAVE_AS = "Save As";
/**
* the constant string 'new'.
*/
static final private String NEW = "New";
/**
* the constant string 'color'.
*/
static final private String color = "Color";
/**
* string oval for easy access for buttons.
*/
static String oval = new String("oval");
/**
* string line for easy access for buttons.
*/
static String line = new String("line");
/**
* string circle for easy access for buttons.
*/
static String circle = new String("circle");
/**
* string rectangle for easy access for buttons.
*/
static String rectangle = new String("rectangle");
/**
* string square for easy access for buttons.
*/
static String square = new String("square");
/**
* ShapeFrame constructor.
*/
public ShapeFrame(){
super();
}
/**
* method that add buttons.
* #param toolBar Jtoolbar.
* #param btn Jbuttons.
*/
protected void addButtons(JToolBar toolBar, JButton btn) {
toolBar.add(btn);
}
/**
* method that add radio buttons.
* #param toolBar Jtoolbar.
* #param btn JRadioButton.
*/
protected void addRadioButtons(JToolBar toolBar, JRadioButton btn) {
toolBar.add(btn);
}
/**
* method that creates button.
* #param btnNam button name.
* #param actionCommand calling from string constant.
* #param toolTipText the message that will appear if cursor was hover over.
* #param altText alternative text.
* #return button Jbutton.
*/
protected JButton btnmaker(String btnNam, String actionCommand, String toolTipText, String altText) {
//Create and initialize the button.
JButton button = new JButton(btnNam);
button.setActionCommand(actionCommand);
button.setToolTipText(toolTipText);
button.addActionListener(this);
return button;
}
/**
* action performed when clicked button.
* #param e mouse click.
*/
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(this, "you have clicked the button");
}
/**
* editlistener for menu bar.
* #author Fu Han
*
*/
private class EditListener implements ActionListener {
/**
* action performed when clicking menu button.
* #param e mouse click.
*/
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand());
}
}
/**
* radio listener for the radio buttons.
* #author
*
*/
private class RadioListener implements ActionListener{
/**
* action performed when click the button.
* #param e mouse click.
*/
public void actionPerformed(ActionEvent e) {
String factoryName = null;
System.out.print("ActionEvent received: ");
if (e.getActionCommand() == oval) {
System.out.println(oval + " pressed.");
drawPad.setCurrentShape(oval);
}else if(e.getActionCommand() == rectangle){
System.out.println(rectangle + " pressed.");
drawPad.setCurrentShape(rectangle);
}else if(e.getActionCommand() == square){
System.out.println(square + " pressed.");
drawPad.setCurrentShape(square);
}else{
System.out.println(line + " pressed.");}
drawPad.setCurrentShape(line);
}
/**
* method for when changes happened after clicking.
* #param e mouse click.
*/
public void itemStateChanged(ItemEvent e) {
}
}
/**
* method for when changes of states that happened after clicking.
* #param e mouse click.
*/
public void stateChanged(ChangeEvent e) {
}
/**
* method for selecting color.
*/
private void selectColor(){
Color newColor = JColorChooser.showDialog(
ShapeFrame.this,
"Choose New Background Color",
Color.RED);
}
/**
* GUI initialization.
*/
public void init(){
Container content = getContentPane();
//Creates a new container
content.setLayout(new BorderLayout());
//sets the layout
final DrawPad drawPad = new DrawPad();
//creates a new padDraw, which is pretty much the paint program
content.add(drawPad, BorderLayout.CENTER);
JMenuBar menubar = new JMenuBar();
EditListener l = new EditListener();
JMenu filem = new JMenu("File");
JMenuItem mi;
mi = filem.add(new JMenuItem("New", 'n'));
mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, Event.CTRL_MASK));
mi.addActionListener(l);
mi = filem.add(new JMenuItem("Open", 'o'));
mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Event.CTRL_MASK));
mi.addActionListener(l);
mi = filem.add(new JMenuItem("Save", 's'));
mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Event.CTRL_MASK));
mi.addActionListener(l);
mi = filem.add(new JMenuItem("Save As", 'a'));
mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Event.CTRL_MASK));
mi.addActionListener(l);
mi = filem.add(new JMenuItem("Exit", 'e'));
mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, Event.CTRL_MASK));
mi.addActionListener(l);
JMenu shapem = new JMenu("Shape");
JMenuItem smi;
smi = shapem.add(new JMenuItem("Line", 'l'));
smi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Event.CTRL_MASK));
smi.addActionListener(l);
smi = shapem.add(new JMenuItem("Circle", 'c'));
smi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A, Event.CTRL_MASK));
smi.addActionListener(l);
smi = shapem.add(new JMenuItem("Rectangle", 'r'));
smi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_U, Event.CTRL_MASK));
smi.addActionListener(l);
smi = shapem.add(new JMenuItem("Square", 'q'));
smi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, Event.CTRL_MASK));
smi.addActionListener(l);
smi = shapem.add(new JMenuItem("Shape Picker", 'p'));
smi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, Event.CTRL_MASK));
smi.addActionListener(l);
menubar.add(filem);
menubar.add(shapem);
menubar.add(Box.createHorizontalGlue());
setJMenuBar(menubar);
//Create the toolbar.
JPanel panel = new JPanel();
JPanel panel2 = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel2.setLayout(new BoxLayout(panel2, BoxLayout.Y_AXIS));
JButton saveBtn = btnmaker("Save",SAVE, "save your paint", "Save");
JButton saveAsBtn = btnmaker("Save As",SAVE_AS, "save your paint to?","Save As");
JButton NewBtn = btnmaker("New",NEW,"new paint","New");
JButton colorbtn = btnmaker("Color",color,"choose color","Color");
colorbtn.setToolTipText("Click this button to select colors.");
colorbtn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg) {
selectColor();
}
});
RadioListener myListener = new RadioListener();
JRadioButton ovalShape = new JRadioButton(oval);
ovalShape.addActionListener(myListener);
ovalShape.setMnemonic(KeyEvent.VK_A);
ovalShape.setActionCommand(oval);
ovalShape.setSelected(true);
add(ovalShape);
JRadioButton rectangleShape = new JRadioButton(rectangle);
rectangleShape.addActionListener(myListener);
rectangleShape.setMnemonic(KeyEvent.VK_A);
rectangleShape.setActionCommand(rectangle);
rectangleShape.setSelected(true);
add(rectangleShape);
JRadioButton squareShape = new JRadioButton(square);
squareShape.addActionListener(myListener);
squareShape.setMnemonic(KeyEvent.VK_A);
squareShape.setActionCommand(square);
squareShape.setSelected(true);
add(squareShape);
JRadioButton lineShape = new JRadioButton(line);
lineShape.addActionListener(myListener);
lineShape.setMnemonic(KeyEvent.VK_B);
lineShape.setActionCommand(line);
add(lineShape);
ButtonGroup group = new ButtonGroup();
group.add(ovalShape);
group.add(lineShape);
group.add(rectangleShape);
group.add(squareShape);
JToolBar toolBar = new JToolBar("File");
JToolBar toolBar2 = new JToolBar("Shape",JToolBar.VERTICAL);
JToolBar toolbar3 = new JToolBar("colors",JToolBar.VERTICAL);
addButtons(toolBar,saveBtn);
addButtons(toolBar,saveAsBtn);
addButtons(toolBar,NewBtn);
addRadioButtons(toolBar2,ovalShape);
addRadioButtons(toolBar2,lineShape);
addRadioButtons(toolBar2,rectangleShape);
addRadioButtons(toolBar2,squareShape);
addButtons(toolbar3,colorbtn);
panel.add(toolBar);
panel2.add(toolBar2);
panel2.add(toolbar3);
content.add(panel, BorderLayout.NORTH);
content.add(panel2, BorderLayout.WEST);
}
}
the DrawPad class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JComponent;
public class DrawPad extends JComponent{
Image image;
//this is gonna be your image that you draw on
Graphics2D graphics2D;
Shape shape;
//this is what we'll be using to draw on
int currentX, currentY, oldX, oldY;
//these are gonna hold our mouse coordinates
String currentShape;
public String getCurrentShape() {
return currentShape;
}
public void setCurrentShape(String currentShape) {
this.currentShape = currentShape;
}
//Now for the constructors
public DrawPad(){
setDoubleBuffered(false);
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
if(currentShape != null){
if(currentShape == "rectangle"){
shape = new Rectangle();
}else if(currentShape == "oval"){
shape = new Oval();
}else if(currentShape == "line"){
shape = new Line();
}else{
shape = new Square();
}
shape.setPoint1(e.getPoint());
shape.setColor(Color.black);
}
}
});
//if the mouse is pressed it sets the oldX & oldY
//coordinates as the mouses x & y coordinates
addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
shape.setPoint2(e.getPoint());
}
});
}
public void paintComponent(Graphics g){
//shape.Draw(g);
if(image == null){
image = createImage(getSize().width, getSize().height);
graphics2D = (Graphics2D)image.getGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
clear();
}
g.drawImage(image, 0, 0, null);
}
//this is the painting bit
//if it has nothing on it then
//it creates an image the size of the window
//sets the value of Graphics as the image
//sets the rendering
//runs the clear() method
//then it draws the image
public void clear(){
graphics2D.setPaint(Color.white);
graphics2D.fillRect(0, 0, getSize().width, getSize().height);
graphics2D.setPaint(Color.black);
repaint();
}
}
and here is the painter program that I look up to:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JComponent;
class PadDraw extends JComponent{
Image image;
//this is gonna be your image that you draw on
Graphics2D graphics2D;
//this is what we'll be using to draw on
int currentX, currentY, oldX, oldY;
//these are gonna hold our mouse coordinates
//Now for the constructors
public PadDraw(){
setDoubleBuffered(false);
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
oldX = e.getX();
oldY = e.getY();
}
});
//if the mouse is pressed it sets the oldX & oldY
//coordinates as the mouses x & y coordinates
addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
currentX = e.getX();
currentY = e.getY();
if(graphics2D != null)
graphics2D.drawLine(oldX, oldY, currentX, currentY);
repaint();
oldX = currentX;
oldY = currentY;
}
});
//while the mouse is dragged it sets currentX & currentY as the mouses x and y
//then it draws a line at the coordinates
//it repaints it and sets oldX and oldY as currentX and currentY
}
public void paintComponent(Graphics g){
if(image == null){
image = createImage(getSize().width, getSize().height);
graphics2D = (Graphics2D)image.getGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
clear();
}
g.drawImage(image, 0, 0, null);
}
//this is the painting bit
//if it has nothing on it then
//it creates an image the size of the window
//sets the value of Graphics as the image
//sets the rendering
//runs the clear() method
//then it draws the image
public void clear(){
graphics2D.setPaint(Color.white);
graphics2D.fillRect(0, 0, getSize().width, getSize().height);
graphics2D.setPaint(Color.black);
repaint();
}
//this is the clear
//it sets the colors as white
//then it fills the window with white
//thin it sets the color back to black
public void red(){
graphics2D.setPaint(Color.red);
repaint();
}
//this is the red paint
public void black(){
graphics2D.setPaint(Color.black);
repaint();
}
//black paint
public void magenta(){
graphics2D.setPaint(Color.magenta);
repaint();
}
//magenta paint
public void blue(){
graphics2D.setPaint(Color.blue);
repaint();
}
//blue paint
public void green(){
graphics2D.setPaint(Color.green);
repaint();
}
//green paint
}
main method for the drawing program:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class paint{
public static void main(String[] args){
Icon iconB = new ImageIcon("blue.gif");
//the blue image icon
Icon iconM = new ImageIcon("magenta.gif");
//magenta image icon
Icon iconR = new ImageIcon("red.gif");
//red image icon
Icon iconBl = new ImageIcon("black.gif");
//black image icon
Icon iconG = new ImageIcon("green.gif");
//finally the green image icon
//These will be the images for our colors.
JFrame frame = new JFrame("Paint It");
//Creates a frame with a title of "Paint it"
Container content = frame.getContentPane();
//Creates a new container
content.setLayout(new BorderLayout());
//sets the layout
final PadDraw drawPad = new PadDraw();
//creates a new padDraw, which is pretty much the paint program
content.add(drawPad, BorderLayout.CENTER);
//sets the padDraw in the center
JPanel panel = new JPanel();
//creates a JPanel
panel.setPreferredSize(new Dimension(32, 68));
panel.setMinimumSize(new Dimension(32, 68));
panel.setMaximumSize(new Dimension(32, 68));
//This sets the size of the panel
JButton clearButton = new JButton("Clear");
//creates the clear button and sets the text as "Clear"
clearButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
drawPad.clear();
}
});
//this is the clear button, which clears the screen. This pretty
//much attaches an action listener to the button and when the
//button is pressed it calls the clear() method
JButton redButton = new JButton(iconR);
//creates the red button and sets the icon we created for red
redButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
drawPad.red();
}
});
//when pressed it will call the red() method. So on and so on =]
JButton blackButton = new JButton(iconBl);
//same thing except this is the black button
blackButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
drawPad.black();
}
});
JButton magentaButton = new JButton(iconM);
//magenta button
magentaButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
drawPad.magenta();
}
});
JButton blueButton = new JButton(iconB);
//blue button
blueButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
drawPad.blue();
}
});
JButton greenButton = new JButton(iconG);
//green button
greenButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
drawPad.green();
}
});
blackButton.setPreferredSize(new Dimension(16, 16));
magentaButton.setPreferredSize(new Dimension(16, 16));
redButton.setPreferredSize(new Dimension(16, 16));
blueButton.setPreferredSize(new Dimension(16, 16));
greenButton.setPreferredSize(new Dimension(16,16));
//sets the sizes of the buttons
panel.add(greenButton);
panel.add(blueButton);
panel.add(magentaButton);
panel.add(blackButton);
panel.add(redButton);
panel.add(clearButton);
//adds the buttons to the panel
content.add(panel, BorderLayout.WEST);
//sets the panel to the left
frame.setSize(500, 500);
//sets the size of the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//makes it so you can close
frame.setVisible(true);
//makes it so you can see it
}
}

Problem #1
Maintaining a reference to the Graphics context and painting outside of a paint cycle. Never maintain a reference to a Graphics context that you did not create yourself. Never paint to a component's Graphics context outside of the paintComponent method call. Painting is destructive, anything drawn to the Graphics context outside of the paint cycle will be lost
Problem #2
Breaking the paint chain. Unless you a VERY good reason to do otherwise, you should always call super.paintComponent BEFORE you perform any custom painting. Also paintComponent never needs to be public, no one should ever be calling it...
Problem #3
currentShape == "line" is not how String comparison works. Use "line".equals(currentShape) instead...
Problem #4
setDoubleBuffered(false);...this just means a lot more work for you...paint to the Graphics context which is passed to the paintComponent, WHEN it's passed to the paintComponent method...
Problem #5
Beware of what you are adding what to...
Container content = getContentPane();
content.setLayout(new BorderLayout());
final DrawPad drawPad = new DrawPad();
content.add(drawPad, BorderLayout.CENTER);
//...
//Create the toolbar.
JPanel panel = new JPanel();
JPanel panel2 = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel2.setLayout(new BoxLayout(panel2, BoxLayout.Y_AXIS));
//...
// What do you think this is been added to?
add(ovalShape);
//...
// What do you think this is been added to?
add(rectangleShape);
//...
// What do you think this is been added to?
add(squareShape);
//...
// What do you think this is been added to?
add(lineShape);
//...
panel.add(toolBar);
panel2.add(toolBar2);
panel2.add(toolbar3);
content.add(panel, BorderLayout.NORTH);
content.add(panel2, BorderLayout.WEST);
BorderLayout will only show the last item that was added to any of it's five available slots...which would, in this case, lineShape...
Take a look at...
Painting in AWT and Swing
Performing Custom Painting
Recommendations
Prototype small elements of your problem, understand how the work in isolation and then figure out how to plug them into a large set of functionality...

Related

My Save Method is only saving the Background and not the Draw Image in Java GUI

I'm making a Java GUI that has a panel where you can scribble on it. I want to save the scribbled image after drawing it. However, my save method only saves the background and not the drawing.
Here is part of the constructor for my GUI. The important part is the scribblePane2 object which is the section of the GUI where the image is drawn.
public GUI(){
// Create the main scribble pane component, give it a border, and
// a background color, and add it to the content pane
scribblePane = new ScribblePane2();
scribblePane.setBorder(new BevelBorder(BevelBorder.LOWERED));
scribblePane.setBackground(Color.black);
contentPane.add(scribblePane, BorderLayout.CENTER);
}
Here is the scribblePane2 class where I take the mouse input to draw the image in the panel. The method "lineto" is where I draw the lines in response to mouse input. I tried drawing to the buffered image, bufferImage, but it did not work for me.
class ScribblePane2 extends JPanel {
BufferedImage bufferImage;
public ScribblePane2() {
// Give the component a preferred size
setPreferredSize(new Dimension(200, 200));
bufferImage = new BufferedImage(200, 200,
BufferedImage.TYPE_INT_ARGB);
Graphics2D bufferGraphics = bufferImage.createGraphics();
}
/** Draw from the last point to this point, then remember new point */
public void lineto(int x, int y) {
Graphics g = getGraphics();
g.setColor(color);
((Graphics2D) g).setStroke(new BasicStroke(10));// Tell it what color to use
g.drawLine(last_x, last_y, x, y);
moveto(x, y);
}
public BufferedImage getImage (){
return bufferImage;
}
}
Here is my method to save the image. I tried by creating a Buffered Image of the scribblePane and a doing the screen capture which is the line commented out. Both have not worked.
public static void saveDrawing(int i) {
BufferedImage imagebuf = null;
//imagebuf = new Robot().createScreenCapture(scribblePane.getBounds());
imagebuf = new BufferedImage(scribblePane.WIDTH, scribblePane.HEIGHT, BufferedImage.TYPE_INT_RGB);
//imagebuf = scribblePane.getImage();
Graphics2D graphics2D = imagebuf.createGraphics();
scribblePane.paint(graphics2D);
try {
ImageIO.write(imagebuf, "png", new File("save" + i +".png"));
System.out.println("image saved");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("error");
}
}
For reference, here is all of my code.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.border.BevelBorder;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import javax.imageio.ImageIO;
public class GUI {
private static int i;
private static JButton button;
private static JButton button2;
private static JLabel label;
private static ScribblePane2 scribblePane;
private static JPanel contentPane;
private Path mPath;
private Paint mBitmapPaint;
private Paint mPaint;
//private Bitmap mBitmap;
private Canvas mCanvas;
BufferedImage bufferImage;
public static void main(String[] args){
new GUI();
setUpButtonListeners();
// Scribble scribble = new Scribble();
//scribble.setSize(500, 300);
//scribble.setVisible(true);
}
public GUI(){
JFrame frame = new JFrame();
frame.setSize(300,300);
GridBagLayout layout = new GridBagLayout();
JPanel panel = new JPanel();
JPanel panel2 = new JPanel();
label = new JLabel("number");
JLabel label2 = new JLabel("Hi I'm contentPane");
contentPane = new JPanel();
contentPane.add(label2);
button = new JButton("Classify Image");
button2 = new JButton("Erase Image");
// Specify a layout manager for the content pane
contentPane.setLayout(new BorderLayout());
// Create the main scribble pane component, give it a border, and
// a background color, and add it to the content pane
scribblePane = new ScribblePane2();
scribblePane.setBorder(new BevelBorder(BevelBorder.LOWERED));
scribblePane.setBackground(Color.black);
contentPane.add(scribblePane, BorderLayout.CENTER);
// Create a menubar and add it to this window. Note that JFrame
// handles menus specially and has a special method for adding them
// outside of the content pane.
JMenuBar menubar = new JMenuBar(); // Create a menubar
//frame.setJMenuBar(menubar); // Display it in the JFrame
// Create menus and add to the menubar
JMenu filemenu = new JMenu("File");
JMenu colormenu = new JMenu("Color");
menubar.add(filemenu);
// menubar.add(colormenu);
// Create some Action objects for use in the menus and toolbars.
// An Action combines a menu title and/or icon with an ActionListener.
// These Action classes are defined as inner classes below.
Action black = new ColorAction(Color.black);
Action red = new ColorAction(Color.red);
Action blue = new ColorAction(Color.blue);
// Populate the menus using Action objects
// colormenu.add(black);
// Now create a toolbar, add actions to it, and add it to the
// top of the frame (where it appears underneath the menubar)
JToolBar toolbar = new JToolBar();
// contentPane.add(toolbar, BorderLayout.NORTH);
// Create another toolbar for use as a color palette and add to
// the left side of the window.
JToolBar palette = new JToolBar();
palette.add(black);
palette.setOrientation(SwingConstants.VERTICAL);
// contentPane.add(palette, BorderLayout.WEST);
panel.setBorder(BorderFactory.createEmptyBorder(30,30,10,30));
panel.setLayout(layout);
panel2.setLayout(new BorderLayout());
panel2.add(label, BorderLayout.WEST);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(contentPane, gbc);
gbc.gridx = 1;
gbc.gridy = 0;
panel.add(panel2,gbc);
gbc.gridx = 0;
gbc.gridy = 2;
//gbc.fill = GridBagConstraints.HORIZONTAL;
//gbc.gridwidth = 2;
panel.add(button, gbc);
gbc.gridx = 1;
gbc.gridy = 2;
panel.add(button2, gbc);
//panel.setLayout(new BorderLayout());
//panel.add(button, BorderLayout.WEST);
//panel.add(button2, BorderLayout.EAST);
//panel.add(label, BorderLayout.NORTH);
//panel.add(contentPane, BorderLayout.SOUTH);
frame.add(panel);
frame.setTitle("GUI");
frame.pack();
frame.setVisible(true);
}
public static void setUpButtonListeners(){
ActionListener buttonListener = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
System.out.println("save");
int output = 0;
saveDrawing(i);
i++;
label.setText("" + output);
}
};
ActionListener buttonListener2 = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
System.out.println("erase");
scribblePane.clear();
label.setText("");
}
};
button.addActionListener(buttonListener);
button2.addActionListener(buttonListener2);
}
public static void saveDrawing(int i) {
//throws AWTException {
BufferedImage imagebuf = null;
//imagebuf = new Robot().createScreenCapture(scribblePane.getBounds());
imagebuf = new BufferedImage(scribblePane.WIDTH, scribblePane.HEIGHT, BufferedImage.TYPE_INT_RGB);
//imagebuf = scribblePane.getImage();
Graphics2D graphics2D = imagebuf.createGraphics();
scribblePane.paint(graphics2D);
try {
ImageIO.write(imagebuf, "png", new File("save" + i +".png"));
System.out.println("image saved");
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("error");
}
}
private void loadImageFromStorage(String path)
{
System.out.println("load");
//use a fileInputStream to read the file in a try / catch block
// try {
// File f=new File(path, "drawn_image.jpg");
// Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
// ImageView img=(ImageView)findViewById(R.id.outputView);
// img.setImageBitmap(b);
// }
// catch (FileNotFoundException e)
// {
/// e.printStackTrace();
// }
}
/** This inner class defines the "clear" action that clears the scribble */
/** This inner class defines the "quit" action to quit the program */
/**
* This inner class defines an Action that sets the current drawing color of
* the ScribblePane2 component. Note that actions of this type have icons
* rather than labels
*/
class ColorAction extends AbstractAction {
Color color;
public ColorAction(Color color) {
this.color = color;
putValue(Action.SMALL_ICON, new ColorIcon(color)); // specify icon
}
public void actionPerformed(ActionEvent e) {
scribblePane.setColor(color); // Set current drawing color
}
}
/**
* This inner class implements Icon to draw a solid 16x16 block of the
* specified color. Most icons are instances of ImageIcon, but since we're
* only using solid colors here, it is easier to implement this custom Icon
* type
*/
static class ColorIcon implements Icon {
Color color;
public ColorIcon(Color color) {
this.color = color;
}
// These two methods specify the size of the icon
public int getIconHeight() {
return 16;
}
public int getIconWidth() {
return 16;
}
// This method draws the icon
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(color);
g.fillRect(x, y, 16, 16);
}
}
}
class ScribblePane2 extends JPanel {
BufferedImage bufferImage;
public ScribblePane2() {
// Give the component a preferred size
setPreferredSize(new Dimension(200, 200));
bufferImage = new BufferedImage(200, 200,
BufferedImage.TYPE_INT_ARGB);
Graphics2D bufferGraphics = bufferImage.createGraphics();
// Register a mouse event handler defined as an inner class
// Note the call to requestFocus(). This is required in order for
// the component to receive key events.
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
moveto(e.getX(), e.getY()); // Move to click position
requestFocus(); // Take keyboard focus
}
});
// Register a mouse motion event handler defined as an inner class
// By subclassing MouseMotionAdapter rather than implementing
// MouseMotionListener, we only override the method we're interested
// in and inherit default (empty) implementations of the other methods.
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
lineto(e.getX(), e.getY()); // Draw to mouse position
}
});
// Add a keyboard event handler to clear the screen on key 'C'
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_C)
clear();
}
});
}
/** These are the coordinates of the the previous mouse position */
protected int last_x, last_y;
/** Remember the specified point */
public void moveto(int x, int y) {
last_x = x;
last_y = y;
}
/** Draw from the last point to this point, then remember new point */
public void lineto(int x, int y) {
Graphics g = getGraphics();
/// BufferedImage newBufferedImage = new BufferedImage(200,200,
//BufferedImage.TYPE_INT_ARGB);
/// Graphics g = newBufferedImage.getGraphics();
// Get the object to draw with
g.setColor(color);
((Graphics2D) g).setStroke(new BasicStroke(10));// Tell it what color to use
g.drawLine(last_x, last_y, x, y); // Tell it what to draw
//g.drawImage(bufferImage, x,y,null);
//bufferImage = newBufferedImage;// Save the current point
moveto(x, y);
}
public BufferedImage getImage (){
return bufferImage;
}
/**
* Clear the drawing area, using the component background color. This method
* works by requesting that the component be redrawn. Since this component
* does not have a paintComponent() method, nothing will be drawn. However,
* other parts of the component, such as borders or sub-components will be
* drawn correctly.
*/
public void clear() {
repaint();
}
/** This field holds the current drawing color property */
Color color = Color.white;
/** This is the property "setter" method for the color property */
public void setColor(Color color) {
this.color = color;
}
/** This is the property "getter" method for the color property */
public Color getColor() {
return color;
}
}

JLabel not displaying initially

I have made a simple class to practice layouts. most of it is working fine, but my JLabel is not appearing until after I click the button. I had the same info as a JTextField and JTextArea in earlier versions, but really prefer the appearance of the JLabel, but even in the other iterations, it would only appear if I clicked on or tried to select the text from the window. I've tried setting the text variable to visible after generating it, after adding it to the under panel, and setting the whole under panel to visible in addition to the setVisible(true) called for the whole object, and none of those worked.
Here is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LayoutPractice extends JFrame implements ActionListener {
//Set up variables
private JPanel graphic;
private JPanel under;
private JButton button;
private JLabel text;
private int clicks;
/**
* Constructor, sets up GUI
*
*/
public LayoutPractice(){
//Default JFrame setup
super("Layout Practice");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the graphic panel
this.graphic = new JPanel();
graphic.setPreferredSize(new Dimension(500, 500));
//Set up the components that go under the graphic
this.clicks = 0;
this.button = new JButton("Click for dialog");
this.text = new JLabel("No Clicks");
//Set up the under panel, add in the button and label
this.under = new JPanel();
under.setLayout(new FlowLayout());
under.add(button);
under.add(text);
//Tell it to react to the button being pressed
button.addActionListener(this);
//Set the panels onto the JFrame
getContentPane().add(graphic, BorderLayout.CENTER);
getContentPane().add(under, BorderLayout.PAGE_END);
//Pack and set the JFrame to visible
pack();
setVisible(true);
}
/**
* Paints the image displayed on graphic
*
* #param A Graphics object to be worked on
*
*/
public void paint(Graphics g) {
//Assigns which panel to paint
graphic.paint(g);
//Set a color to pains
g.setColor(Color.BLUE);
//Use variables for a pattern
int x = 0;
int y = 0;
//Loop for a pattern
while (x <= 230) {
//Generates a filled rectangle of the correct size
g.fillRect(x, y, (500-(2 * x)), (500-(2 * y)));
//Alternates color
if (g.getColor() == Color.BLUE) {
g.setColor(Color.ORANGE.darker());
}
else {
g.setColor(Color.BLUE);
}
//Increase variables to reduce rectangle size
x += 20;
y += 20;
}
}
/**
* Tells the GUI what to do when the button is pressed
*
* #param An ActionEvent, specifically the buton being pressed
*/
public void actionPerformed(ActionEvent event) {
//Increase the clicks variable
clicks++;
//Change/update the JLabel
text.setText("Clicks: " + clicks);
//Open a dialog using available tools
JOptionPane.showMessageDialog(new JFrame(),
("Clicks: " + clicks),
"Click Count",
JOptionPane.INFORMATION_MESSAGE);
}
/**
* Very simple main, makes a new LayoutPractice
*
* #param args
*/
public static void main(String[] args) {
new LayoutPractice();
}
}
The quick fix is to just call super.paint(g) at the beginning of your overriden paint method, so that the frame ensures its clearing/cleaning/layout correctly.
The best fix takes the following into account :
When overriding a method, add the #Override annotation, so that your IDE will warn you if you incorrectly override .
When overriding a painting method , call its super implementation to ensure that things get correctly cleaned by the parent component.
For custom painting, better use a JComponent (usually a JPanel).
For custom painting, override paintComponent(Graphics) (and call super.paintComponent), don't use paint(Graphics).
You don't need to extend JFrame, just create one JFrame and use it.
In the below example, a custom JPanel class has been added for custom painting, and the application doesn't extend JFrame anymore :
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
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.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class LayoutPractice implements ActionListener {
//Set up variables
private final JPanel graphic;
private final JPanel under;
private final JButton button;
private final JLabel text;
private int clicks;
/**
* Constructor, sets up GUI
*
*/
public LayoutPractice() {
//Default JFrame setup
JFrame frame = new JFrame("Layout Practice");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the graphic panel
graphic = new GraphicPanel();
graphic.setPreferredSize(new Dimension(500, 500));
//Set up the components that go under the graphic
clicks = 0;
button = new JButton("Click for dialog");
text = new JLabel("No Clicks");
//Set up the under panel, add in the button and label
under = new JPanel();
under.setLayout(new FlowLayout());
under.add(button);
under.add(text);
//Tell it to react to the button being pressed
button.addActionListener(this);
JPanel mainPanel = new JPanel(new BorderLayout());
//Set the panels onto the JFrame
mainPanel.add(graphic, BorderLayout.CENTER);
mainPanel.add(under, BorderLayout.PAGE_END);
frame.setContentPane(mainPanel);
//Pack and set the JFrame to visible
frame.pack();
frame.setVisible(true);
}
/**
* Tells the GUI what to do when the button is pressed
*
* #param An ActionEvent, specifically the buton being pressed
*/
public void actionPerformed(final ActionEvent event) {
//Increase the clicks variable
clicks++;
//Change/update the JLabel
text.setText("Clicks: " + clicks);
//Open a dialog using available tools
JOptionPane.showMessageDialog(new JFrame(),
("Clicks: " + clicks),
"Click Count",
JOptionPane.INFORMATION_MESSAGE);
}
/**
* Very simple main, makes a new LayoutPractice
*
* #param args
*/
public static void main(final String[] args) {
new LayoutPractice();
}
private class GraphicPanel extends JPanel {
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
//Set a color to pains
g.setColor(Color.BLUE);
//Use variables for a pattern
int x = 0;
int y = 0;
//Loop for a pattern
while (x <= 230) {
//Generates a filled rectangle of the correct size
g.fillRect(x, y, (500 - (2 * x)), (500 - (2 * y)));
//Alternates color
if (g.getColor() == Color.BLUE) {
g.setColor(Color.ORANGE.darker());
} else {
g.setColor(Color.BLUE);
}
//Increase variables to reduce rectangle size
x += 20;
y += 20;
}
}
}
}

How can i make an array holding the walls

I need a simple do loop for my game but don't know how to create one.
I have a simple maze game.
I still need to add more walls
I was thinking of creating an array and calling the index of the array in the do loop to call the wall but i dont now how to do it
I was thinking that I could create a do loop instead of copying and pastinn the collision code 30 times.
My player needs to be reset to the beginning when it touches a wall
The player is s simple JLabel.My walls are also a JLabel.I'm using swing components for my game.
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
/**
* This class Holds the game pane that has the moving player. It also contains
* the GamePane
*
* #author 602052004
*
*/
public class GamePane extends JPanel implements ActionListener, KeyListener {// *change GamePane to GamePane
// This is where the game screen is made and the player is created.
private static final long serialVersionUID = 1L;
JLabel player = new JLabel();
//This is were the Jlabels for the walls are created
JLabel wall1 = new JLabel();
JLabel wall2 = new JLabel();
JLabel wall3 = new JLabel();
JLabel wall4 = new JLabel();
JLabel wall5 = new JLabel();
int playerSpeed = 5;
int FPS = 40;
private final Set<Integer> keys = new HashSet<>();
// The keys set holds the keys being pressed
public static void main(String[] args) {
// Open the GUI window
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// Create a new object and
// run its go() method
new GamePane().go();
}
});
}
GamePane() {
// Run the parent class constructor
super();
// Allow the panel to get focus
setFocusable(true);
// Don't let keys change the focus
}
/**
* The frame that shows my game. It contains the game frame which holds my
* JPanel GameStage and ButtonPane.
*/
protected void go() {
setLayout(new CardLayout());
// Setup the window
JFrame GameFrame = new JFrame();
// Add this panel to the window
GameFrame.setLayout(new CardLayout());
GameFrame.add(this, "main");
GameFrame.setContentPane(this);
// Set's the window properties
GameFrame.setTitle("main");
GameFrame.setSize(800, 600);
GameFrame.setLocationRelativeTo(null);
GameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GameFrame.setVisible(true);
GameFrame.add(new ButtonPane(GameFrame), "buttons");
// Creates the new JPanel that will hold the game.
JPanel gamestage = new JPanel();
gamestage.setBackground(Color.darkGray);
GameFrame.add(gamestage, "game");
gamestage.setLayout(null);
// *Move the setup of the player and the timer under the walls
// Get a sample of collisions going so that i can do it over the weekend
// Setup the movable box
player.setBounds(25, 25, 20, 20);
player.setVisible(true);
player.setBackground(Color.cyan);
// Opaque makes the background visible
player.setOpaque(true);
// Setup the key listener
addKeyListener(this);
// Null layout allows moving objects!!!
gamestage.add(player);
// Set the timer
Timer tm = new Timer(1000 / FPS, this);
tm.start();
wall1.setBounds(10, 15, 10, 480);
wall1.setVisible(true);
wall1.setBackground(Color.white);
wall1.setOpaque(true);
gamestage.add(wall1);
wall2.setBounds(10, 10, 755, 10);
wall2.setVisible(true);
wall2.setBackground(Color.white);
wall2.setOpaque(true);
gamestage.add(wall2);
// wall3.setBounds(x, y, width, height);
wall3.setBounds(10, 100, 100, 10);
wall3.setVisible(true);
wall3.setBackground(Color.white);
wall3.setOpaque(true);
gamestage.add(wall3);
wall4.setBounds(100, 60, 10, 40);
wall4.setVisible(true);
wall4.setBackground(Color.white);
wall4.setOpaque(true);
gamestage.add(wall4);
wall5.setBounds(70, 60, 35, 10);
wall5.setVisible(true);
wall5.setBackground(Color.white);
wall5.setOpaque(true);
gamestage.add(wall5);
}
public boolean areColliding(JLabel a, JLabel b) {
return a.getBounds().intersects(b.getBounds());
}
/**
* this method makes the player move. It takes the players speed and subtracts
* or adds the player speed to the current position of the player. It also
* figures out were the player is at currently aswell.
*
* #param arg0
*/
#Override
public void actionPerformed(ActionEvent arg0) {
// Move up if W is pressed
if (keys.contains(KeyEvent.VK_W)) {
player.setLocation(player.getX(), player.getY() - playerSpeed);
}
// Move right if D is pressed
if (keys.contains(KeyEvent.VK_D)) {
player.setLocation(player.getX() + playerSpeed, player.getY());
}
// Move down if S is pressed
if (keys.contains(KeyEvent.VK_S)) {
player.setLocation(player.getX(), player.getY() + playerSpeed);
}
// Move left if A is pressed
if (keys.contains(KeyEvent.VK_A)) {
player.setLocation(player.getX() - playerSpeed, player.getY());
}
// Check for collisions
if (areColliding(wall1, player)) {
// Reposition the target
int newX = (int) (25);
int newY = (int) (25);
player.setLocation(newX, newY);}
}
#Override
public void keyPressed(KeyEvent e) {
// Add the key to the list
// of pressed keys
if (!keys.contains(e.getKeyCode())) {
keys.add(e.getKeyCode());
}
}
#Override
public void keyReleased(KeyEvent e) {
// Remove the key from the
// list of pressed keys
keys.remove((Integer) e.getKeyCode());
}
#Override
public void keyTyped(KeyEvent e) {
}
}
This is just for you to have a running main screen to go to when playing the game
/**
* This pane contains the button and sets up the button pane
*/
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ButtonPane extends JPanel {
private JButton startBTN;// Calls the JButton
JFrame game;
public ButtonPane(JFrame g) {
game = g;
setLayout(new GridBagLayout());
setBackground(Color.gray);// Sets the menu stages color blue
startBTN = new JButton("Start");// Creates a new button
add(startBTN);// Adds the button on the startStage
startBTN.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (game.getContentPane().getLayout() instanceof CardLayout) {
CardLayout layout = (CardLayout) getParent().getLayout();
layout.show(game.getContentPane(), "game");
}
}
});
}
}
The basic idea is to place all the objects that the player can collide with in a List.
On each movement of the player, loop over this list and use the Rectangle#contains and Rectangle#intersects provided by the component's getBounds methods
Which might look something like this...
public class GamePane extends JPanel implements ActionListener, KeyListener {// *change GamePane to GamePane
private List<JComponent> collidableStuff;
public GamePane() {
collidableStuff = new ArrayList<>(25);
//...
wall1 = ...;
wall2 = ...;
wall3 = ...;
wall4 = ...;
wall5 = ...;
// In fact, you could get rid of wall1-5 and just
// use the list instead
collidableStuff.add(wall1);
collidableStuff.add(wall2);
collidableStuff.add(wall3);
collidableStuff.add(wall4);
collidableStuff.add(wall5);
//...
}
#Override
public void actionPerformed(ActionEvent e) {
//...
player.setLocation(newX, newY);
performCollisionDetection();
}
protected void performCollisionDetection() {
Rectangle playerBounds = player.getBounds();
for (JComponent nonPassable : collidableStuff) {
// Because I didn't test the code, I'm covering all bases
Rectangle nonPassableBounds = nonPassable.getBounds();
if (nonPassableBounds.contains(playerBounds) || playerBounds.contains(nonPassableBounds)
|| playerBounds.intersects(nonPassableBounds) || nonPassableBounds.intersects(playerBounds)) {
// Smack, we have a collision
}
}
}
}
This example moves the responsibility of the creation of the objects to the constructor, rather the then the go method, which, frankly shouldn't exist - the GamePane shouldn't care about "how" it's been shown, that's not it's responsibility

Java Swing GUI changing colour on mouse over

I am relatively new to the Java Swing library and I am attempting to write a tic tac toe program with a 3 by 3 grid of JButtons. When a user selects a button, I am changing the background colour of the row and column that contains the selected button to add a highlighted feel (by changing the button.setBackground() of each JButton to a different colour).
However, I am currently having an issue where the new background colour is removed (and changed back to the old background colour) when the mouse is dragged over one of the highlighted buttons.
There appears to be a mouse event that is repainting the button when the mouse enters the button, however I have tried and failed to turn this event off.
I would greatly appreciate any help! If I need to clarify anything please let me know. Thanks
Set the background to NULL if you want to change the button back to it's default:
button.setBackground(inBounds ? new Color(0xFFFF00) : null);
Here is an example I whipped up. You can use it as a reference.
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class GridRollOver extends JFrame implements MouseListener {
private static final long serialVersionUID = -7134685459910610342L;
public JButton[] buttons = new JButton[9];
public GridRollOver() {
this.setLayout(new GridLayout(3, 3));
for (int i = 0; i < 9; i++) {
JButton b = new JButton();
b.setRolloverEnabled(true);
b.addMouseListener(this);
this.add(b);
buttons[i] = b;
}
this.setVisible(true);
this.setSize(500, 500);
this.setLocationRelativeTo(null);
}
public static void main(String[] args) {
new GridRollOver();
}
public void highlightButtons(Point cursor) {
for (int i = 0; i < buttons.length; i++) {
JButton button = buttons[i];
Point buttonLocation = button.getLocationOnScreen();
double west = buttonLocation.getX();
double east = buttonLocation.getX() + button.getWidth();
double north = buttonLocation.getY();
double south = buttonLocation.getY() + button.getHeight();
boolean inRow = cursor.getX() > west && cursor.getX() < east;
boolean inCol = cursor.getY() > north && cursor.getY() < south;
boolean inBounds = inRow || inCol;
button.setBackground(inBounds ? new Color(0xFFFF00) : null);
}
}
#Override
public void mouseEntered(MouseEvent event) {
highlightButtons(event.getLocationOnScreen());
}
#Override
public void mouseExited(MouseEvent e) { }
#Override
public void mouseClicked(MouseEvent e) { }
#Override
public void mousePressed(MouseEvent e) { }
#Override
public void mouseReleased(MouseEvent e) { }
}
In which you can change the color of button when mouse entered on the button when mouse exit it change to it default color by using MouseListener method mouseEntered(MouseEvent e) and mouseExited(MouseEvent e).
package listener;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* This class is used to show when mouse arrow on the button its color change when exited it again on it same color
* #author Ganesh Patel
*
*/
public class ButtonColorChanger implements MouseListener{
JFrame frame;
JButton buttonArray[];
JPanel contentPane;
public ButtonColorChanger() {
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = createContentPane();
frame.setContentPane(contentPane);
frame.setVisible(true);
frame.pack();
}
/**
* This method is used to create content pane and add 9 button and call the MouseListener on every button
* #return panel content pane of the frame
*/
public JPanel createContentPane() {
JPanel panel = new JPanel(new GridLayout(3,3));
buttonArray = new JButton[9];
//add 9 button on the panel and call MouseListener on every button
for(int i = 0; i<buttonArray.length; i++) {
buttonArray[i] = new JButton(" O ");
buttonArray[i].addMouseListener(this);
panel.add(buttonArray[i]);
}
return panel;
}
#Override
public void mouseClicked(MouseEvent e) {
}
/**
*This method is used for change the color of button when mouse on it.
*/
#Override
public void mouseEntered(MouseEvent e) {
JButton button = (JButton)e.getSource();
button.setBackground(Color.RED);
}
/**
* This method is used to change the color of button when mouse is not on it.
*/
#Override
public void mouseExited(MouseEvent e) {
JButton button = (JButton)e.getSource();
button.setBackground(null);
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
public static void main(String args[]) {
new ButtonColorChanger();
}
}

Java GUI for drawing a large, zoomable, interactive diagram

I have tried to draw a diagram in Swing with a large number (thousands) of JLabels inside a large number of nestled JPanels, all with different layouts.
I made the whole diagram zoomable, zooming one step i use setPrefferedSize() on all of the components in the diagram.
It is also interactive, by clicking at one of the JLabels, the program zooms in on that JLabel. Each JLabel has a tooltip and changes color when hovered over.
The problem is that when the diagram is too large, the zoom is far to slow. There is a for-loop that has to go trough all of the JComponents in the diagram and change their prefered size. Then I have to call .revalidate() on the JComponents parent.
So my questions are:
Instead of using the nestled JPanels with different layouts for the structure, should I only use one JPanel with null Layout and use setBounds() on all of the JLabels to position and zoom in on them? Will it be lighter for the computer?
Should I use another GUI? It has to support the following:
Draw rectangular labels with tooltips, can add a mouseListener.
Zoomable, can scale the whole diagram
Can draw text in the diagram.
Scrollable, can add the diagram to a JScrollPane (important when zooming in)
You could forget the individual JLabels and just draw your text items in the paintComponent method of the main JPanel.
You can use drawString to draw the items of text.
Also, you can keep a "zoom level" value and draw the strings at different positions/sizes depending on that zoom level.
If I were you I'd knock up a quick example of this to draw a few thousand strings, and see if that's fast enough on your target spec client machine.
EDIT: Something like this:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
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;
/**
* TestPaintComponentZooming
*
* #author davidf
*/
public class TestPaintComponentZooming {
private JFrame f;
private JPanel panel;
private double zoom = 1.0;
public static void main(String[] args) {
TestPaintComponentZooming t = new TestPaintComponentZooming();
t.init();
}
public TestPaintComponentZooming() {
}
public void init() {
JButton b = new JButton();
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
b.setPreferredSize(new Dimension(600, 10));
panel = new _JPanel();
panel.add(b);
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(panel, "Center");
f.add(getCheckBoxPanel(), "South");
f.setLocation(200, 200);
f.setSize(400, 400);
f.validate();
f.setVisible(true);
}
private JPanel getCheckBoxPanel() {
JButton zoomIn = new JButton("Zoom in");
zoomIn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
zoomAndRepaint(0.1);
}
});
JButton zoomOut = new JButton("Zoom out");
zoomOut.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
zoomAndRepaint(-0.1);
}
});
JPanel panel2 = new JPanel();
panel2.add(zoomIn);
panel2.add(zoomOut);
return panel2;
}
/**
* zoomAndRepaint
*/
protected void zoomAndRepaint(double d) {
zoom += d;
f.repaint();
}
private class _JPanel extends JPanel {
public _JPanel() {
super(null);
}
/**
* #see javax.swing.JComponent#paintComponent(java.awt.Graphics)
*/
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setFont(new Font("Arial", Font.PLAIN, (int) (zoom * 10 + 2)));
for (int x=0; x < 100; x++) {
for (int y=0; y < 100; y++) {
g.drawString("Hello " + x + "," + y, (int) (x * 60 * zoom), (int) (y * 10 * zoom));
}
}
}
}
}

Categories

Resources