Java: Adding events to dynamically created components - java

I'm building a UI in Java. I want to create new components, like a JLabel, using a button. So every time I click a button it creates a new JLabel and places them in a specific JPanel.
Then, I want to be able to do some things with the labels based on how the user clicks on them.
With a left mouse press I want them to be able to drag the labels around the screen.
With a right mouse click I want to be open a new window where certain data can be entered, tied to the label (which might involve dynamically creating variables).
I've been toying around with some code I've Googled around for. I can get a button to create new labels in a panel, but when I try to get them to drag, I can only get one label at a time to appear, and after a second button press, moving the label isn't smooth, it jumps around.
I haven't even tried to implement any of the right mouse click things yet. If anyone can point me in the right direction, I'd appreciate it.
public class Testing {
JFrame frame;
//Launch the application.
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
Testing window = new Testing();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
//Create the application.
public Testing() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
JPanel area;
JButton btnCreate;
JLabel dragLabel;
frame = new JFrame();
frame.setBounds(100, 100, 511, 542);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
frame.setVisible(true);
area = new JPanel();
area.setBounds(10, 11, 477, 404);
frame.getContentPane().add(area);
area.setLayout(new BorderLayout());
btnCreate = new JButton("Create Label");
dragLabel = new JLabel("Drag Me");
btnCreate.setBounds(10, 425, 477, 67);
frame.getContentPane().add(btnCreate);
btnCreate.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
area.add(dragLabel);
area.revalidate();
DragListener drag = new DragListener();
dragLabel.addMouseListener(drag);
dragLabel.addMouseMotionListener(drag);
}
});
}
}
class DragListener extends MouseInputAdapter
{
Point location;
MouseEvent pressed;
public void mousePressed(MouseEvent me) {
pressed = me;
}
public void mouseDragged(MouseEvent me)
{
if(SwingUtilities.isLeftMouseButton(me)){
Component component = me.getComponent();
location = component.getLocation(location);
int x = location.x - pressed.getX() + me.getX();
int y = location.y - pressed.getY() + me.getY();
component.setLocation(x, y);
}
}
}
EDIT - I'm fairly certain the primary issue is in how the JLabel itself is being added to the panel. Every time the button is being pushed it's adding the same label over again, and this is gumming up the works.
Unfortunately, I'm not sure how to deal with that. I've done a bit more digging, and since dynamic variables aren't possible, I'm going to have to use an array or a map or some sort. With that, it appears I can declare arrays of components. Would something like that be necessary for my purposes?

Really odd stuff in your code. I don't want to go everything, and I'm not an expert by any stretch of the imagination, but I tried to remove redundant or contradictory stuff. I suspect a part of what you did was just copy pasting bits without really fitting them into the code.
Anyway, you needed to create the label inside the listener, so that it creates a new one everytime you click. Otherwise you only ever create one label and just reuse the same everytime.
I implemented a dialog on right click to enter the label name, don't know what you wanted to do but at least it detects right clicks.
Also in general it's easier to use layout managers instead of hardcoding everything. Here you had a borderlayout but were ignoring it.
class Main {
//Launch the application.
public static void main(String[] args) {
DrageableLabel window = new DrageableLabel();
}
}
public class DrageableLabel {
public DrageableLabel() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
JFrame frame = new JFrame();
Container area = frame.getContentPane();
area.setLayout(new BorderLayout());
JButton btnCreate = new JButton("Create Label");
btnCreate.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
/*
This is where you create your new window
for now I've added a dialog that takes a string parameter and creates a label with that string
I moved the method code to create a new drageable label outside the actionlistener to make it less confusing and reuseable
Either build w-e you want directly in here
or call a method that does it (which I prefer)
*/
String string = JOptionPane.showInputDialog(frame, "Enter your message", "Messages", JOptionPane.CANCEL_OPTION);
addDrageableLabel(string, area);
} else if (SwingUtilities.isLeftMouseButton(e)) {
addDrageableLabel("Drag me", area);
}
}
});
area.add(btnCreate, BorderLayout.SOUTH);
frame.setBounds(100, 100, 511, 542);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
// This is the method that creates and adds a drageable label
public void addDrageableLabel(String labelName, Container container) {
JLabel dragLabel = new JLabel(labelName);
container.add(dragLabel, BorderLayout.CENTER);
container.validate();
DragListener drag = new DragListener();
dragLabel.addMouseListener(drag);
dragLabel.addMouseMotionListener(drag);
}
}
class DragListener extends MouseInputAdapter {
Point location;
MouseEvent pressed;
#Override
public void mousePressed(MouseEvent me) {
pressed = me;
}
#Override
public void mouseDragged(MouseEvent me) {
Component component = me.getComponent();
location = component.getLocation(location);
int x = location.x - pressed.getX() + me.getX();
int y = location.y - pressed.getY() + me.getY();
component.setLocation(x, y);
}
}

Related

JTable and JButton click not working

I have a JPanel holding a JButton and JScrollPane (in turn holding a JTable) and am currently running into two issues which I believe are related:
The JButton listener's actionPerformed() method is not invoked upon click. The only way in which I can get it to be invoked is by calling doClick() on the JButton. The JButton color changes upon hover but no click animation is shown when the mouse is pressed.
Secondly, if a cell is clicked within the JTable, the cell located 2 rows down in the same column registers the click instead. This offset does not occur when clicking in the column headers (i.e. to adjust cell widths), only when within the cell area.
Left-hand panel. Click position circled
public class InventoryPanel extends JPanel {
// Parent Business object reference for communication and JFrame
private Business parent;
private AddItemPanel addItemPanel;
// Inventory table items
private DefaultTableModel inventoryModel;
private JTable inventoryTable;
private JScrollPane inventoryScrollPane;
private JLabel updateLbl;
private JButton addItemBtn;
// Columns for inventory table
private static final String[] INVENTORY_COLUMNS = {"Item","Stock","Restocking Level","Edit"};
public InventoryPanel(Business parent) {
this.parent = parent;
initGUI();
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
//doStuff
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace(new PrintStream(System.out));
}
}
}
}).start();
}
// INITIALISES GUI
public void initGUI() {
this.setLayout(new BoxLayout(this,BoxLayout.PAGE_AXIS));
this.setBorder(BorderFactory.createLineBorder(Color.BLACK));
JLabel titleLabel = new JLabel("<html><B>Inventory</B></html>");
this.add(titleLabel);
// Create empty inventory table
inventoryModel = new DefaultTableModel(new Object[3][4],INVENTORY_COLUMNS);
inventoryTable = new JTable(inventoryModel);
inventoryScrollPane = new JScrollPane(inventoryTable);
// Create button to allow items to be added
addItemBtn = new JButton("Add item");
addItemBtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("ADD ITEM PRESSED");
}
});
updateLbl = new JLabel("Loading inventory...");
this.add(addItemBtn);
this.add(inventoryScrollPane);
this.add(updateLbl);
}
I've tried removing the table from the panel to see if that solves the JButton issue and visa-versa, but no luck. I've also tried changing the project JDK but no luck there either.
There are other JPanels adjacent to the troublesome one in a JFrame which work perfectly fine. Any ideas?
Edit: I can create a working instance of the InventoryPanel alone in a frame in another project, as mentioned in the comments. However the exact same code (no calls being made to other objects/methods) in the current project now produces ClassCastExceptions. After some googling this seems to be due to non-EDT threads updating the GUI.
However there is no use of the Business class, and all GUI operations are performed using the SwingUtilities.invokeLater() method like so:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("test");
frame.add(new InventoryPanel());
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
Note: the no-argument constructor InventoryPanel() just calls initGUI().
Thanks for the help so far...still very confused by this.

Java drawing application

I need to develop an application which has 3 buttons for drawing a line,a rectangle and a circle. The application should behave like this: user clicks on a button to draw a wanted shape, mouse cursor changes to a dot, user moves the mouse down to some container, draws two dots by clicking the mouse twice at desired locations and then the wanted shape is drawn using those two dots. From the information I have already gathered, I know I should use a MouseClickListener for drawing the dots and then call a shape class with parameters passed from the dot class to draw the shape. What I need to know is what container to use for the shapes, where to put the MouseClickListener in order to allow drawing only in that container and how to restrict the user from drawing any more points until a button is pressed again.
So far this is my code:
`public class MyPanel {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MyPanel window = new MyPanel();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public MyPanel() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setResizable(false);
frame.setBounds(100, 100, 500, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBackground(Color.WHITE);
panel.setBounds(10, 25, 474, 336);
frame.getContentPane().add(panel);
JButton btnLine = new JButton("Line");
btnLine.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
drawPoint draw = new drawPoint();
}
});
btnLine.setBounds(10, 0, 110, 23);
frame.getContentPane().add(btnLine);
JButton btnRectangle = new JButton("Rectangle");
btnRectangle.setBounds(196, 0, 110, 23);
frame.getContentPane().add(btnRectangle);
JButton btnCircle = new JButton("Circle");
btnCircle.setBounds(374, 0, 110, 23);
frame.getContentPane().add(btnCircle);
}
}
public class drawPoint implements MouseListener {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
getCoordinates
drawAPoint
drawLine(coordinates)
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
}
What I need to know is what container to use for the shapes
Typically, components with custom draw are done by subclassing JPanel and overriding the paintComponent method. Less customary, and arguably more clean from an OO perspective, one may subclass JComponent. But you will find far fewer example code on the web via this route.
where to put the MouseClickListener
On the JPanel subclass would probably work.
in order to allow drawing only in that container
You can't really prevent a user from clicking in the JPanel and dragging outside it. But, you can try to detect this condition, and make sure the code ignores this kind of input.
and how to restrict the user from drawing any more points until a button is pressed again.
Use variables. E.g., a boolean variable ready which is true initially, gets set to false when drawing starts and is reset to true only by a button press. And have your drawing points handler check the ready value and only initiate drawing if it is true. You may need other variables to keep track of how many additional clicks are allowed as part of the current drawing operation.

Changing layout/frame in response to a button press

I'm trying to make a little game on Java using the Swing components (Boggle-type game).
The way I have it set up right now, it basically opens up to the game right away - but I want to have a start up window with two buttons - "Tutorial" and "Play". I already have the functionality (my Tutorial button just opens a new Window with all the things on it) I'm just not sure how to create a second JFrame and then switch to it when I press Play (or rather, create a JFrame, then switch to the one I've already created when the JButton is pressed). I guess I could cause a new JFrame to open on the same location and the old one to become non-visible - but I was hoping for a simpler solution.
I also want to do this on completion of the game, switching again automatically to a little stat page - so any info will be appreciated.
This is what I have so far in case you guys want to see my code (I haven't yet hooked up the Enter key send the userWord to be validated and scored in my other classes, or filled in the tileGrid with Tile Objects, or the timer.... but that will all come later!)
public class Game implements Runnable {
public void run(){
final JFrame frame = new JFrame("Boggle");
frame.setLocation(500,200);
// Input - holds typing box
final JLetterField typingArea = new JLetterField(1);
typingArea.setFocusTraversalKeysEnabled(false);
typingArea.setEditable(true);
typingArea.setFocusable(true);
typingArea.requestFocusInWindow(); //also this request isn't being granted..
//if anyone could explain why i would love you
// I want the focus on the TextField on startup
frame.add(typingArea, BorderLayout.SOUTH);
typingArea.addKeyListener(new KeyAdapter() {
public void keyPressed (KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) { // enter key is pressed
String userWord = typingArea.getText().toLowerCase();
typingArea.setText("");
}
}
});
final JLabel status = new JLabel("Running...");
// Main playing area
GridLayout tileGrid = new GridLayout(4,4);
final JPanel grid = new JPanel(tileGrid);
frame.add(grid, BorderLayout.CENTER);
// Reset button
final JPanel control_panel = new JPanel();
frame.add(control_panel, BorderLayout.NORTH);
final ImageIcon img = new ImageIcon("Instructions.png", "My Instructions...");
final JButton info = new JButton("Help");
info.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
final JFrame infoFrame = new JFrame("Tutorial");
infoFrame.setLocation(500,50);
JLabel tutorialImg = new JLabel(img);
int w = img.getIconWidth();
int h = img.getIconHeight();
infoFrame.setSize(w, h);
infoFrame.add(tutorialImg);
infoFrame.setVisible(true);
}
});
control_panel.add(info);
// Put the frame on the screen
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Game());
}
}
use CardLayout instead of second JFrame, your concept is heading to OutOfMemory
use JFrame.pack(after switch betweens Cards in CardLayout) if you want to change JFrames bounds on runtime,

Thread sleep inside of actionPerformed method

First of all I want to say I'm aware this aproach is wrong so I'm asking this question because of pure curiousity. Lets say I have a swing application like this:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ThreadSleeping {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton button = new JButton("Load");
JLabel label = new JLabel();
public ThreadSleeping() {
panel.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
label.setIcon(new ImageIcon(
"C:/Users/Public/Pictures/Sample Pictures/Tulips.jpg"));
System.out.println("Tulips painted");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
label.setIcon(new ImageIcon(
"C:/Users/Public/Pictures/Sample Pictures/Koala.jpg"));
System.out.println("Koala painted");
}
});
frame.add(panel, BorderLayout.NORTH);
frame.add(label, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(1024, 768);
// frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ThreadSleeping();
}
});
}
}
Basically when I click a Load button I expect that Tulips.jpg image displays then GUI freezes for a 2 seconds and after that I expect that Koala.jpg image displays. But what happens is that: I click on button, GUI freezes for a 2 seconds and Koala.jpg displays. No Tulips.jpg before that. But thing that confuses me is when I put those System.out.println("Tulips painted"); and System.out.println("Koala painted");. So when I click on button it prints "Tulips painted" and after 2 seconds "Koala painted". Can someone tell me whats going on here? Regards.
works in this case, because you programatically freeze ouf Swing GUI, but there is/aren't another update(s), ot another JComponent(s)
doens't works in the case that there are a few another updated to the Swing GUI, Thread.sleep(int) freeze Event Dispatch Thread,
by default all updates to the JComponents XxxModels never will be visible on the JComponents view
example until sleep ended you'll lost all updated to the GUI
The point I intended to make in my comment:
if you sleep the edt, the resulting mis-behaviour is basically unpredictable.
Unpredictable in the sense that you can't know what will happen or not. All we can do, is guess ...
The technical reason is that most ui updates don't happen immediately but are scheduled: we can't really know what's waiting in the line behind us. Remember: it's only one lane, and when in the actionPerformed, it's we that are sitting in it.
For educational reasons, the code below is the original code with a couple of lines to un/comment to demonstrate different scenarios.
[0] resetting the icon before/after sleeping: as you already noticed, the first doesn't show even though the property is taken. Technical reason: visual update happens via label.repaint() which is scheduled on the EDT for latter processing (as its api doc states)
[1] skimming the api doc, we notice another method: paintImmediately(...) which is documented to do exactly what it's name says and allowed - as we are on the EDT - is allowed to be called. Looks like success, the yellow icon shows up.
[2] but wait: being in the center of a Borderline, the label fills that area anyway, independent of whether or not it has an icon. Let's try to put it into a region that requires a re-layout, as f.i. into the south. Back to square [0], yellow icon not showing.
[3] looking into the source of setIcon(..) reveals that layout is ... scheduled again. We learned in square [1] that we can force thingies to happen immediately, in case of layout that would be the pair invalidate() / validate(). Bingo, yellow icon even when in south.
[4] nasty subclass which schedules the icon property setting (note: while contrived here there is nothing in its contract that hinders subclasses to do it!). As the property isn't even set, yellow isn't showing, back to square [0]
At the end of the day (but before going to sleep the EDT :-), there is simply no way to reliably predict the visual outcome during the sleep. And visuals are only the tip of the ice...
/**
* Unpredictable behaviour when sleeping the EDT.
* http://stackoverflow.com/q/15600203/203657
*
* [0] run as-is: property set but yellow not showing
* [1] uncomment paintImmediately: yellow showing in center
* [2] add label to south: yellow not showing
* [3] force immediate in-/validation: yellow showing in south
* [4] subclass label with invoked property setting:
* property not set, yellow not showing
*
*/
public class ThreadSleeping {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton button = new JButton("Load");
JLabel label = new JLabel() {
// [4] subclass implemented to schedule the property setting
// #Override
// public void setIcon(final Icon icon) {
// SwingUtilities.invokeLater(new Runnable() {
// public void run() {
// superSetIcon(icon);
//
// }
// });
// }
//
// protected void superSetIcon(Icon icon) {
// super.setIcon(icon);
// }
//
};
public ThreadSleeping() {
panel.add(button);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
Icon firstIcon = new FixedIcon(Color.YELLOW, 100, 100);
Icon secondIcon = new FixedIcon(Color.RED, 500, 500);
label.setIcon(firstIcon);
// check if the property is already set
System.out.println(label.getIcon());
// following lines try to force the output before going to sleep
// [3] paintImmediately + force immediate re-layout
// label.invalidate();
// label.getParent().validate();
// {1] paintImmediately (fine for center, no effect for south)
// ((JComponent) label.getParent()).paintImmediately(0, 0, 5000, 5000);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
label.setIcon(secondIcon);
}
});
frame.add(panel, BorderLayout.NORTH);
// un/comment one of the following, placing the
// label either in CENTER (= sized to fill)
frame.add(label, BorderLayout.CENTER);
// [2] or in SOUTH (= sized to pref)
// frame.add(label, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(1024, 768);
frame.setVisible(true);
}
/**
* Simple fixed size Icon filling its area.
*/
public static class FixedIcon implements Icon {
private Color background;
private int width;
private int height;
public FixedIcon(Color background, int width, int height) {
this.background = background;
this.width = width;
this.height = height;
}
#Override
public void paintIcon(Component c, Graphics g, int x, int y) {
g.setColor(background);
g.fillRect(0, 0, width, height);
}
#Override
public int getIconWidth() {
return width;
}
#Override
public int getIconHeight() {
return height;
}
#Override
public String toString() {
return "[" + background + " w/h " + width + "/" + height + "]";
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new ThreadSleeping();
}
});
}
}

Fast Jbutton clicks results in no action

Hey guys, I have a problem with a code that I've been writing.
I have a JFrame that contains two buttons. Each of these buttons has an action. The problem I'm having is with a JButton called "btnDone" that's supposed to get back to a previous screen. If I I keep pushing the button repeatedly, eventually the "btnDone" would stop doing the logic it's supposed to do. My code is as follows:
For the frame:
public class ItemLocatorPnl extends JPnl
{
private static final long serialVersionUID = 1L;
private Pnl pnl;
private JButton btnDone;
private JButton btnRefreshData;
public void setPnl(Pnl pnl) {
this.pnl = pnl;
}
public ItemLocatorPnl(Pnl pnl)
{
super();
this.pnl=pnl;
initialize();
}
private void initialize()
{
this.setSize(300, 200);
JPanel jContentPane = new JPanel();
jContentPane.setLayout(new MigLayout());
// (1) Remove window frame
setUndecorated(true);
// (3) Set background to white
jContentPane.setBackground(Color.white);
// (5) Add components to the JPnl's contentPane
POSLoggers.initLog.writeDebug("ItemLocator: Adding icon");
jContentPane.add(wmIconLabel, "align left");
POSLoggers.initLog.writeDebug("ItemLocator: Adding global controls");
jContentPane.add(createUpperPanel(), "align right, wrap");
POSLoggers.initLog.writeDebug("ItemLocator: Adding main panel");
jContentPane.add(pnl,"width 100%,height 100%, span 3");
// (6) Attach the content pane to the JPnl
this.setContentPane(jContentPane);
}
private JPanel createUpperPanel()
{
JPanel upperPanel=new JPanel();
MigLayout mig = new MigLayout("align right", "", "");
upperPanel.setLayout(mig);
upperPanel.setBackground(Color.WHITE);
// Create the Done button
btnDone= GraphicalUtilities.getPOSButton("<html><center>Done</center></html>");
btnDone.addActionListener(new ButtonListener());
// Create the Refresh Data button
btnRefreshData = GraphicalUtilities.getPOSButton("<html><center>Refresh<br>Data</center></html>");
btnRefreshData.addActionListener(new ButtonListener());
//Addiing buttons to the Panel
upperPanel.add(btnRefreshData, "width 100:170:200, height 100!");
upperPanel.add(btnDone, "width 100:170:200, height 100!");
return upperPanel;
}
public class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
if (e.getSource() == btnRefreshData) {
Actual.refreshData();
} else if (e.getSource() == btnDone) {
Actual.backToMainScreen();
}
}
catch (Exception ex)
{
}
}
}
}
This is the method that the btnDone button calls upon clicking:
public static void backToMainScreen()
{
frame.setVisible(false);
frame.dispose();
}
This is the code that displays the JFrame:
public static void displayItemLocatorFrame()
{
pnl = new Pnl();
frame = new Frame(pnl);
frame.setVisible(true);
pnl.getSearchCriteria().requestFocus();
}
Please note that the "frame" object is static, and all of my methods are static, and they exist in a static class called Actual.
So in short, I just want to make sure that no matter how many times a user clicks on the button, and no matter how fast the clicks were, the frame should act normally.
Any suggestions? (I tried synchronizing my methods with no luck..)
I would generally prefer to use an Action for what you're trying to do.
So your code might look like this:
btnDone = new JButton(new CloseFrameAction());
...
private class CloseFrameAction extends AbstractAction
{
public CloseFrameAction()
{
super("Done");
}
public void actionPerformed(ActionEvent e)
{
frame.dispose();
setEnabled(false);
}
}
Notice the setEnabled(false) line - this should disable the button and prevent the user clicking on it again. Obviously I don't know what your exact requirements are but this is the general approach I would take.
The problem was with using a static panel that was instantiated with the click of the button each time. Removing "static" has finally fixed my problem! Thanks everyone for the help.

Categories