repaint() isn't called in Java program - java

I have a simple program (most of it is going to be used for something else) that just draws ovals when a user clicks the drawPanel JPanel and displays ovals. The problem is that the repaint() method isn't calling paintComponent(). Why is this?
Here is the code:
// Imports Used:
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
import java.awt.geom.*;
// Class DrawPolygon
public class DrawPolygon extends JPanel implements MouseListener
{
// Variables used in GUI
static JFrame frame;
static JPanel drawPanel;
static JPanel labelPanel;
static JPanel primaryPanel;
static JButton loadButton;
static JButton saveButton;
static JButton clearButton;
static JButton addButton;
static JButton moveButton;
static JButton exitButton;
// Variables used for GUI interaction
static final int SIZE = 6;
static int numVertices;
ArrayList<Point> vertices;
static Color outlineColor = Color.RED;
static int lineWidth = 10;
static Color fillColor = Color.BLACK;
// Constructor for new Polygon Drawing Application
public DrawPolygon()
{
// Create Frame
frame = new JFrame("Vector Painter");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set Location of GUI on screen
frame.setLocation(225,100);
// Primary Panel to store Draw Panel and Lable/Button Panel
primaryPanel = new JPanel();
// Create Label Panel
createLabelPanel();
// Create Draw Panel
createDrawPanel();
// Add panels to Primary
primaryPanel.add(labelPanel);
primaryPanel.add(drawPanel);
// Add to frame
frame.getContentPane().add(primaryPanel);
frame.pack();
frame.setVisible(true);
}
// Add Buttons to left side
public void createLabelPanel()
{
// Label Panel to add Buttons
labelPanel = new JPanel();
labelPanel.setBackground(Color.BLACK);
labelPanel.setPreferredSize(new Dimension(200,600));
// Create JButtons
loadButton = new JButton("LOAD");
loadButton.setPreferredSize(new Dimension(180,75));
loadButton.setBackground(Color.BLACK);
loadButton.setForeground(Color.WHITE);
loadButton.addMouseListener(this);
saveButton = new JButton("SAVE");
saveButton.setPreferredSize(new Dimension(180,75));
saveButton.setBackground(Color.BLACK);
saveButton.setForeground(Color.WHITE);
saveButton.addMouseListener(this);
clearButton = new JButton("CLEAR");
clearButton.setPreferredSize(new Dimension(180,75));
clearButton.setBackground(Color.BLACK);
clearButton.setForeground(Color.WHITE);
clearButton.addMouseListener(this);
addButton = new JButton("ADD");
addButton.setPreferredSize(new Dimension(180,75));
addButton.setBackground(Color.BLACK);
addButton.setForeground(Color.WHITE);
addButton.addMouseListener(this);
moveButton = new JButton("MOVE");
moveButton.setPreferredSize(new Dimension(180,75));
moveButton.setBackground(Color.BLACK);
moveButton.setForeground(Color.WHITE);
moveButton.addMouseListener(this);
exitButton = new JButton("EXIT");
exitButton.setPreferredSize(new Dimension(180,75));
exitButton.setBackground(Color.BLACK);
exitButton.setForeground(Color.WHITE);
exitButton.addMouseListener(this);
// Add Buttons to Label Panel
labelPanel.add(loadButton);
labelPanel.add(saveButton);
labelPanel.add(clearButton);
labelPanel.add(addButton);
labelPanel.add(moveButton);
labelPanel.add(exitButton);
}
// Creates Draw Panel
public void createDrawPanel()
{
// Draw Panel to Draw Polygons
drawPanel = new JPanel();
drawPanel.setBackground(Color.BLACK);
drawPanel.setPreferredSize(new Dimension(600,600));
drawPanel.addMouseListener(this);
vertices = new ArrayList<>();
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.ORANGE);
for (Point spot : vertices)
{
g.fillOval(spot.x-SIZE, spot.y-SIZE, SIZE*2, SIZE*2);
}
g.drawString("Count: " + vertices.size(), 5, 15);
System.out.println("repaint is working?");
}
// Execute when Load button is clicked
public void loadButton()
{
System.out.println("Load Button CLICKED!!");
}
// Execute when Save button is clicked
public void saveButton()
{
System.out.println("Save Button CLICKED!!");
}
// Execute when Clear button is clicked
public void clearButton()
{
System.out.println("Clear Button CLICKED!!");
}
// Execute when Add button is clicked
public void addButton()
{
System.out.println("Add Button CLICKED!!");
}
// Execute when Move button is clicked
public void moveButton()
{
System.out.println("Move Button CLICKED!!");
}
public void mouseClicked(MouseEvent e)
{
if (e.getSource() == loadButton)
{
loadButton();
}
else if (e.getSource() == saveButton)
{
saveButton();
}
else if (e.getSource() == clearButton)
{
clearButton();
}
else if (e.getSource() == addButton)
{
addButton();
}
else if (e.getSource() == moveButton)
{
moveButton();
}
else if (e.getSource() == exitButton)
{
System.exit(0);
}
else if (e.getSource() == drawPanel)
{
System.out.println("TEST");
vertices.add(e.getPoint());
repaint();
}
}
// These are here because program wouldn't compile without them
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
// Main Function
public static void main(String[] args)
{
// Create Frame
new DrawPolygon();
}
}

Actually repaint is being called, but on the current DrawPolygon object, but since you don't seem to be displaying one of these paintComponent(...) won't ever be called. To clarify, your current class, DrawPolygon, extends JPanel, but it doesn't seem to have been added to any container that is part of your GUI hierarchy. Perhaps you want to add your current object, your this, to the GUI somewhere? In fact you probably should consider using your current object in place of the your drawPanel JPanel object. I would consider just deleting that variable entirely.
Also unrelated to your problem, you almost never want to use MouseListeners on JButtons where ActionListeners should instead be used.

Related

Simple paint program using JPanel shows random images of JButtons

I'm trying to make a simple paint program in Java. It has 3 colors and a JField to enter the thickness. It works, except every time I enter a button, an image of that button shows up in the JPanel that contains the drawing portion.
I know that I can set the paintPane JPanel to opaque, but it relies on drawing over it self for the painting to work - otherwise it just drags a point around the screen. Thanks!!!
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class SimplePainting
{
//The main method simply creates a frame, and terminates the program
//once that frame is closed.
public static void main (String [] args)
{
PaintFrame frame = new PaintFrame();
frame.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
}
}
class PaintFrame extends JFrame implements ActionListener
{
JPanel pane;
PaintPane drawPane;
Color paintColor = Color.black;
private int radius = 5;
//holds the thickness of the line
JTextField thick;
public PaintFrame ()
{
//We use the JFrame consturctor to add a title to the frame
super("Windows Paint");
//set the main content pane
pane = (JPanel)getContentPane();
pane.setLayout(new BorderLayout());
//make a pane to hold the drawing
drawPane = new PaintPane();
drawPane.addMouseMotionListener(drawPane);
//Make a JPanle to hold all of the buttons
JPanel buttonPane = new JPanel();
buttonPane.setLayout(new GridLayout(1,6));
//add the buttons
JButton black = new JButton("Black");
buttonPane.add(black);
JButton red = new JButton("Red");
buttonPane.add(red);
JButton green = new JButton("Green");
buttonPane.add(green);
//Make a field to re-enter the thickness
thick = new JTextField(3);
thick.setText("5");
JButton thickness = new JButton("Reset Thickness");
thickness.addActionListener(this);
buttonPane.add(thickness);
buttonPane.add(thick);
JButton reset = new JButton("New Drawing");
reset.addActionListener(this);
buttonPane.add(reset);
black.addActionListener(this);
red.addActionListener(this);
green.addActionListener(this);
pane.add(drawPane, BorderLayout.CENTER);
pane.add(buttonPane, BorderLayout.SOUTH);
setSize(500,200);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("Black"))
paintColor = Color.black;
else if (e.getActionCommand().equals("Red"))
paintColor = Color.red;
else if (e.getActionCommand().equals("Green"))
paintColor = Color.green;
else if (e.getActionCommand().equals("Reset Thickness"))
{
if (thick.getText() != "")
{
int lineThickness = Integer.parseInt(thick.getText());
radius = lineThickness;
}
}
else if (e.getActionCommand().equals("New Drawing"))
{
drawPane.startPaint = false;
drawPane.repaint();
}
}
class PaintPane extends JPanel implements MouseMotionListener
{
private int x;
private int y;
// don't paint a point until mouse is dragged
boolean startPaint = false;
public PaintPane()
{
setBackground(Color.white);
}
//paints a circle centered at x,y
public void paint(Graphics g)
{
//recall that the frist (x,y) coordiantes represent the top left
//corner of a box holding the circle
g.setColor(paintColor);
if (startPaint)
g.fillOval(x-radius,y-radius, 2*radius, 2*radius);
else
super.paintComponent(g);
}
public void mouseDragged(MouseEvent e)
{
startPaint = true;
x = e.getX();
y = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e)
{
}
}
}

Round JButton with icon; gets clicked when not directly pointer at; setting cursor to HAND_CURSOR works on area outside the icon

So, I have JFrame with JPanel on it. JPanel has two JToggleButtons. Each button is displayed as an icon of a round button. When the cursor hovers above a button it is supposed to turn into a hand.
public class UserInterface extends JFrame {
int width;
int height;
JPanel panel;
public static void main(String[] args) {
run();
}
public UserInterface() {
setup();
}
private void setup() {
width=800;
height=600;
panel=new UserInterfacePanel();
add(panel);
setSize(width, height);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void run() {
UserInterface gui=new UserInterface();
gui.setVisible(true);
}
}
class UserInterfacePanel extends JPanel {
private JToggleButton startButton;
private JToggleButton stopButton;
public static void main(String[] args) {
}
public UserInterfacePanel() {
setup();
}
private void setup() {
setLayout(new GridLayout(1,2));
setupButtons();
setupButtonsActions();
add(startButton);
add(stopButton);
}
private void setupButtons() {
ImageIcon iconStartButton = new ImageIcon("C:\\Users\\parsecer\\Desktop\\imgs\\greenReleased.png");
ImageIcon iconStopButton=new ImageIcon("C:\\Users\\parsecer\\Desktop\\imgs\\redReleased.png");
startButton=new JToggleButton(iconStartButton);
stopButton=new JToggleButton(iconStopButton);
startButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
stopButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
startButton.setHorizontalAlignment(JButton.CENTER);
stopButton.setHorizontalAlignment(JButton.CENTER);
startButton.setAlignmentX(CENTER_ALIGNMENT);
stopButton.setAlignmentX(CENTER_ALIGNMENT);
startButton.setAlignmentY(CENTER_ALIGNMENT);
stopButton.setAlignmentY(CENTER_ALIGNMENT);
setupButtonIcon(startButton);
setupButtonIcon(stopButton);
ImageIcon iconStartButtonPressed=new ImageIcon("C:\\Users\\parsecer\\Desktop\\imgs\\greenPressed.png");
startButton.setDisabledIcon(iconStartButton);
startButton.setPressedIcon(iconStartButtonPressed);
startButton.setSelectedIcon(iconStartButtonPressed);
ImageIcon iconStopButtonPressed=new ImageIcon("C:\\Users\\parsecer\\Desktop\\imgs\\redPressed.png");
stopButton.setDisabledIcon(iconStopButton);
stopButton.setPressedIcon(iconStopButtonPressed);
stopButton.setSelectedIcon(iconStopButtonPressed);
}
private void setupButtonIcon(JToggleButton button) {
button.setBorder(BorderFactory.createEmptyBorder());
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setFocusable(false);
button.setPreferredSize(new Dimension(80, 80));
button.setFocusPainted(false);
button.setOpaque(false);
}
}
The problem is, the cursor changes into a hand way beyond the icon itself. The same goes for clicking the button - the button get pressed wherever I click vertically - given it's in the same column as the button or when I get relatively close to it horizontally.
I suppose the first problem might be linked to button image, but the background is deleted. Can the second be linked to the GridLayout?
I would do something like this:
Define the shape of your buttons, presumably a circle/ellipse.
In your click- and motionlisteners check if the event occured inside of that shape. If so, do your thing.
Put into code it would go (for the motionlistener) like this:
Cursor handCursor = new Cursor(Cursor.HAND_CURSOR);
Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR);
// create your shape here
Shape shape = new Ellipse2D.Float(0, 0, 30, 30);
MouseMotionAdapter motionListener = new MouseMotionAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
super.mouseMoved(e);
JToggleButton src = (JToggleButton) e.getSource();
if (shape.contains(e.getPoint())) {
src.setCursor(handCursor);
} else {
src.setCursor(normalCursor);
}
}
};
startButton.addMouseMotionListener(motionListener);
stopButton.addMouseMotionListener(motionListener);

Buttons and Icons Within a Label - SquareIcon

I am trying to create a program with three buttons and a label with a CompositeIcon that at the start is empty.
When you click one of the buttons there will be added a square at the screen (with the described color), when another button is pressed there is gonna be added another square and so on. That means, when i press a button five times, there will be created five squres at the given colors.
If any one will read my code i will be thankful.
/*
This program creates a window with three buttons - red, green and blue - and a label with an icon.
This icon is a CompositeIcon that at the start is empty. When we press one of the three buttons, there will
be added a square at the specified color.
*/
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ResponsiveFrame extends JFrame {
static SquareIcon icon;
static int number; // this
static Color awtColor; // this
public static void main(String[] args) {
final JFrame frame = new JFrame();
final JLabel label = new JLabel();
JButton redButton = new JButton("RED");
JButton greenButton = new JButton("GREEN");
JButton blueButton = new JButton("BLUE");
/*
this is the part that i am not sure about!
not sure about the parameters.
*/
icon = new SquareIcon(number, awtColor);
redButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
icon.addIcon(new SquareIcon(20, Color.RED));
label.setIcon(icon);
frame.repaint();
frame.pack();
}
});
greenButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
icon.addIcon(new SquareIcon(20, Color.GREEN));
label.setIcon(icon);
frame.repaint();
frame.pack();
}
});
blueButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
icon.addIcon(new SquareIcon(20, Color.BLUE));
label.setIcon(icon);
frame.repaint();
frame.pack();
}
});
frame.setLayout(new FlowLayout());
frame.add(redButton);
frame.add(greenButton);
frame.add(blueButton);
frame.add(label);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
And here is the part with the SquareIcon.
import java.util.*;
import java.awt.*;
import javax.swing.*;
public class SquareIcon implements Icon {
private ArrayList<Icon> icons;
private int width;
private int height;
public SquareIcon(int number, Color awtColor) {
icons = new ArrayList<Icon>();
number = number;
awtColor = awtColor;
}
public void addIcon(Icon icon) {
icons.add(icon);
width += icon.getIconWidth();
int iconHeight = icon.getIconHeight();
if (height < iconHeight)
height = iconHeight;
}
public int getIconHeight() {
return height;
}
public int getIconWidth() {
return width;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
for (Icon icon : icons) {
icon.paintIcon(c, g, x, y);
x += icon.getIconWidth();
}
}
}
The program does compile, but when i press the buttons, nothing happens!
You create a JLabel but add it to nothing.
I suggest that you create a new JLabel each time you need one, and be sure to add it to the GUI after creating it. You will want to add it to a JPanel that is displayed in the JFrame/GUI, and will want to call revalidate() and repaint() on the JPanel after adding the label so that the panel knows to re-layout all its components, including the new one, and to re-draw itself and its children.

how to replace jpanel with anotherjpanel on jframe when button is clicked

I want the JPanel at the center of the frame to be replaced when the corresponding buttons present in the JPanel to the left of the frame are pressed.
I am using cardlayout for replacing the panels in the center.
here is the sample code that i used for changing panels on button click ,but it doesn't work. can anyone let me know whats wrong in the code.
Library extends JFrame
Public Library(){
Container container = getContentPane();
container.setLayout( new BorderLayout() );
setExtendedState(JFrame.MAXIMIZED_BOTH);
banner = new BannerPanel();
container.add(banner,BorderLayout.NORTH);
MenuButtons = new MenuButtonPanel();
container.add(MenuButtons,BorderLayout.WEST);
SelectedButtonPanel = new SelectedPanel(container);
setLocationRelativeTo(null);
setVisible( true );
init();
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
MenuButtonPanel extends JPanel and has multiple buttons in it. The inner class of it ButtonHandler implements hte actionListner for the buttons
//inner class
class ButtonEventHandler implements ActionListener {
public void actionPerformed( ActionEvent event ){
SelectedPanel selectObj = new SelectedPanel();
if("about".equals(event.getActionCommand()))
{
selectObj.showReplacePanel("about");
}
else if("checkout".equals(event.getActionCommand()))
{
selectObj.showReplacePanel("checkout");
}
else if("search".equals(event.getActionCommand()))
{
selectObj.showReplacePanel("search");
}
The SelectedPanel should display the replaced Jpanel in the center of the frame
public SelectedPanel() {}
public SelectedPanel(Container framePane)
{
addSelectedPanel(framePane);
}
public void addSelectedPanel(Container framePane)
{
cardPanel = new JPanel();
//set layout of panel
cardPanel.setLayout(new CardLayout());
cardPanel.setBorder(null);
cardPanel.setForeground(new Color(0, 0, 0));
//this.selObj = selObj;
aboutPanel = new About();
checkoutPanel = new Checkout();
searchPanel = new Search();
cardPanel.add(aboutPanel,ABOUTBUTTON);
cardPanel.add(checkoutPanel,CHECKOUTBUTTON);
cardPanel.add(searchPanel, SEARCHBUTTON);
framePane.add(cardPanel, BorderLayout.CENTER); }
The selectedPanel class also has method showReplacePanel() which is called in the actionPerformed of the buttonClick.
public void showReplacePanel(String selObj)
{
System.out.println("cardlayout entered");
CardLayout cl = (CardLayout)(cardPanel.getLayout());
System.out.println("cardlayout entered");
switch(selObj){
case "about":
cl.show(cardPanel,ABOUTBUTTON);
break;
case "search":
//this.repPanel = searchPanel;
cl.show(cardPanel,SEARCHBUTTON);
break;
case "checkout":
cl.show(cardPanel,CHECKOUTBUTTON);
//this.repPanel = checkoutPanel;
break;
I created an example for you, take a look at the actionPerformed(ActionEvent e) method
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PanelSwap extends JPanel implements ActionListener {
JPanel firstPanel = new JPanel();
JPanel secondPanel = new JPanel();
public PanelSwap() {
super(new BorderLayout());
firstPanel.setBackground(Color.RED);
secondPanel.setBackground(Color.YELLOW);
JButton swap1 = new JButton("SwapToYellow");
swap1.addActionListener(this);
JButton swap2 = new JButton("SwapToRed");
swap2.addActionListener(this);
firstPanel.add(swap1);
secondPanel.add(swap2);
add(firstPanel);
}
/** Listens to the buttons and perfomr the swap. */
public void actionPerformed(ActionEvent e) {
for (Component component : getComponents())
if (firstPanel == component) {
remove(firstPanel);
add(secondPanel);
} else {
remove(secondPanel);
add(firstPanel);
}
repaint();
revalidate();
}
/**
* Create the GUI and show it. For thread safety, this method should be
* invoked from the event-dispatching thread.
*/
private static void createAndShowGUI() {
// Create and set up the window.
JFrame frame = new JFrame("PanelSwap");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create and set up the content pane.
JComponent newContentPane = new PanelSwap();
newContentPane.setOpaque(true); // content panes must be opaque
frame.setContentPane(newContentPane);
// Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}

Delete a specific button

I have a JPanel in a JFrame that contains 5 buttons. In another JPanel there is a button called "delete button", what I want to do is to click this button and than choose what button of the other 5 to delete by ckicking in one of them. Can anyone help me?
public class gui extends JFrame implements ActionListener
{
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p2 = new JPanel();
JButton b1 = new JButton("Delete");
JButton b2 = new JButton("A");
JButton b3 = new JButton("B");
JButton b4 = new JButton("C");
gui()
{
p1.setLayout(new GridLayout(1,2));
p1.add(p2);
p1.add(p3);
p2.setLayout(new GridLayout(3,1));
p2.add(b2);
p2.add(b3);
p2.add(b4);
p3.add(b1);
b1.addActionListener(this);
b2.addActionListener(this);
b3.addActionListener(this);
b4.addActionListener(this);
}
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == b1)
// When I click this button I want to be able to delete a button of my choice (one of the other 3)
}
}
Use a chain of responsibility in the button listeners. One Button listener that listens for the "to be deleted" buttons and the "delete" button. Under normal operation this button listener just sends the "to be deleted" button events to the existing button events, but when it hears a "delete" button event, it then captures the "next" button event without sending it to the existing button listener, and acts to remove the button.
Ok you provided some code. Here is a solution that uses a chain of responsibility. Basically, if one ActionListener can't handle the event, it sends it to the next one, and so on.
import java.awt.GridLayou;
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.WindowConstants;
public class Gui extends JFrame {
public static final long serialVersionUID = 1L;
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
JPanel p3 = new JPanel();
JButton b1 = new JButton("Delete");
JButton b2 = new JButton("A");
JButton b3 = new JButton("B");
JButton b4 = new JButton("C");
public Gui() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
p1.setLayout(new GridLayout(1, 2));
p1.add(p2);
p2.add(p3);
p2.setLayout(new GridLayout(3, 1));
p2.add(b2);
p2.add(b3);
p2.add(b4);
p3.add(b1);
DoItListener doIt = new DoItListener(null);
DeleteItListener deleteIt = new DeleteItListener(this, doIt);
b1.addActionListener(deleteIt);
b2.addActionListener(deleteIt);
b3.addActionListener(deleteIt);
b4.addActionListener(deleteIt);
add(p1);
pack();
}
public void deleteButton(String name) {
if (b2 != null && "A".equals(name)) {
p2.remove(b2);
b2 = null;
p2.invalidate();
p2.redraw();
}
if (b3 != null && "B".equals(name)) {
p2.remove(b3);
b3 = null;
p2.invalidate();
p2.redraw();
}
if (b4 != null && "A".equals(name)) {
p2.remove(b4);
b4 = null;
p2.invalidate();
p2.redraw();
}
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Gui().setVisible(true);
}
});
}
}
class DoItListener implements ActionListener {
private ActionListener delegate;
public DoItListener(ActionListener next) {
delegate = next;
}
public void actionPerformed(ActionEvent e) {
if (!("Delete".equals(e.getActionCommand()))) {
System.out.println("doing " + e.getActionCommand());
} else if (delegate != null) {
delegate.actionPerformed(e);
}
}
}
class DeleteItListener implements ActionListener {
private Gui gui;
private boolean deleteNext;
private ActionListener delegate;
public DeleteItListener(Gui container, ActionListener next) {
gui = container;
delegate = next;
deleteNext = false;
}
public void actionPerformed(ActionEvent e) {
if ("Delete".equals(e.getActionCommand())) {
deleteNext = true;
} else if (deleteNext) {
gui.deleteButton(e.getActionCommand());
deleteNext = false;
} else if (delegate != null) {
delegate.actionPerformed(e);
}
}
}
Here try this code out :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DeleteButtonExample extends JFrame
{
private boolean deleteNow = false;
private JButton deleteButton;
private JPanel leftPanel;
private JPanel rightPanel;
private JButton[] buttons = new JButton[5];
private ActionListener deleteAction = new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
JButton button = (JButton) ae.getSource();
if (deleteNow)
{
leftPanel.remove(button);
leftPanel.revalidate();
leftPanel.repaint();
deleteNow = false;
}
else
{
// Do your normal Event Handling here.
System.out.println("My COMMAND IS : " + button.getActionCommand());
}
}
};
private void createAndDisplayGUI()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationByPlatform(true);
setLayout(new GridLayout(0, 2));
leftPanel = new JPanel();
leftPanel.setLayout(new GridLayout(0, 2));
leftPanel.setBackground(Color.WHITE);
for (int i = 0; i < 5; i++)
{
buttons[i] = new JButton("" + i);
buttons[i].addActionListener(deleteAction);
buttons[i].setActionCommand("" + i);
leftPanel.add(buttons[i]);
}
rightPanel = new JPanel();
rightPanel.setBackground(Color.BLUE);
JButton deleteButton = new JButton("DELETE");
deleteButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
JOptionPane.showMessageDialog(null, "Delete any Button from the Left Panel by clicking it."
, "INFO : ", JOptionPane.INFORMATION_MESSAGE);
deleteNow = true;
}
});
rightPanel.add(deleteButton);
add(leftPanel);
add(rightPanel);
pack();
setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new DeleteButtonExample().createAndDisplayGUI();
}
});
}
}
OUTPUT :
, ,
Here's a snippet of code to kick you off in the right direction:
import java.awt.event.ActionEvent;
import javax.swing.*;
public class FrameTestBase extends JFrame {
public static void main(String args[]) {
FrameTestBase t = new FrameTestBase();
final JPanel p = new JPanel();
final JButton button = new JButton();
button.setAction(new AbstractAction("Remove me!") {
#Override
public void actionPerformed(ActionEvent e) {
p.remove(button);
p.revalidate();
p.repaint();
}
});
p.add(button);
t.setContentPane(p);
t.setDefaultCloseOperation(EXIT_ON_CLOSE);
t.setSize(400, 400);
t.setVisible(true);
}
}
Before click:
After click:
From the comments:
To generalize this, you could create an AbstractAction that takes the to-be-deleted button as argument. Use this AbstractAction, and update it as necessary whenever your delete-policy should change.
Have a look at the glass pane. This tutorial shows how it is used.
At a high level, clicking the 'Delete' button would put the glass pane listener into a state where it:
detects a click,
determines the target component,
determines whether the component is allowed to be deleted
and if so, delete the component.
As a design note, I would keep a Set of controls that are allowed to be deleted, and thereby separate the concerns. So when you add a button that is allowed to be deleted, it is your responsibility to also add it to the delete candidates set.
The easiest method:
Add an ActionListener to the button that will remove another one;
Repaint and revalidate the panel where is the button to remove.
Example (in this case the button that will delete another one is called by "deleteBtn" and the button in the another panel that will be removed is called by "btnToDlt" that exists in the "panel"):
deleteBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
panel.remove(btnToDlt);
panel.revalidate();
panel.repaint();
}
});

Categories