I want to open a new window when I click the label. By implementing a key pressed listener. But it is not working. Even nothing is happening.
JLabel lblNewLabel_2 = new JLabel("Create New Account!!!!");
lblNewLabel_2.setForeground(Color.GREEN);
lblNewLabel_2.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
Dosomething();
}
});
private void Dosomething() {
hide();
Account account=new Account();
account.visible();
}
protected static void hide() {
frame.hide();
}
You can use JButton as others say and remove its border to make it look like JLabel but if you really want to use JLabel and detect clicks I think you should write a MouseAdapter for it.
JLabel fooLabel = new JLabel("foo");
fooLabel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
doSomething();
}
}
);
You can also override mouseClicked method but in that case the user must not move the cursor while clicking.
Related
I am trying to connect a button to say "Hi" when the mouse enters it and "Bye" when the mouse leaves. I have been using mouse events with a MouseListener but to no avail.
I'm new to Java and this question has been plaguing me for the last 2 days and I just have not been able to figure it out. Any help would be greatly appreciated.
private abstract class HandlerClass implements MouseListener {
}
private abstract class Handlerclass implements MouseListener {
#Override
public void mouseEntered(java.awt.event.MouseEvent e) {
mousebutton.setText("Hi");
}
#Override
public void mouseExited(java.awt.event.MouseEvent e) {
mousebutton.setText("Bye");
}
}
Try like this. It is working for me.
public class ChangeTextMouseEvent extends Frame
{
static JButton btn;
public ChangeTextMouseEvent()
{
setTitle("ChangeText");
btn = new JButton("SSS");
add(btn);
setVisible(true);
setBounds(0, 0, 100, 100);
}
public static void main(String[] args)
{
ChangeTextMouseEvent frame = new ChangeTextMouseEvent();
btn.addMouseListener(new MouseAdapter(){
#Override
public void mouseExited(MouseEvent e)
{
btn.setText("Bye");
}
#Override
public void mouseEntered(MouseEvent e)
{
btn.setText("Hi");
}
});
}
}
Updating the UI component alone is often not enough; you also have to trigger a repaint action.
In other words: there are two "layers" here. One is the "data model" (where some button knows about its text); the other is the actual "graphical content". The later one comes into existence by somehow displaying the first parts. Therefore both layers need to be addressed in order to make your chances visible to the user.
See here for some examples around that.
(Note: I am aware of the existence of the MouseAdapter-class, but since I am probably overriding all methods later on, the advantage of it is lost?)
I have a class MainProgram.java in which I'm adding several components. Most of them have a Listener (ActionListener, MouseListener, ...), which get's a bit crowded in my main class.
Therefore I am trying to "externalize" those Listeners into their own classes. So far I have used inner classes in my main-class, which makes accessing the variables, components, ... pretty easy and straightforward.
But with the external Listeners I am not sure what is the best way to implement them.
For example, when I want to find out, which of the lables has been clicked, I am getting the event, get the source of the event, cast it to a JLabel and then get the text on the label with which I compare a string!
This works, but seems very prone to errors (what if I change the JLabel-text in my main-class? -> Listener breaks) and pretty unclean.
I've tried to search via google and on StackOverflow for better ways to do this, but only found the inner class approach.
So is there a better way to get access to my components / externalize my listeners?
public class MainProgram extends JFrame {
public MainProgram() {
super("Landing Page");
setSize(400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel westPanel = new JPanel();
JLabel lbl_orderStatus = new JLabel("Order Status");
JLabel lbl_technicalDocu = new JLabel("Technical Documentation");
JLabel lbl_checkReport = new JLabel("Check Report");
MouseListenerBoldFont mouseListenerLabelBoldPlain = new MouseListenerBoldFont();
lbl_orderStatus.addMouseListener(mouseListenerLabelBoldPlain);
lbl_technicalDocu.addMouseListener(mouseListenerLabelBoldPlain);
lbl_checkReport.addMouseListener(mouseListenerLabelBoldPlain);
westPanel.add(lbl_orderStatus);
westPanel.add(lbl_technicalDocu);
westPanel.add(lbl_checkReport);
add(westPanel);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
MainProgram window = new MainProgram();
window.setVisible(true);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
}
The MouseListenerBoldFont.java:
public class MouseListenerBoldFont implements MouseListener{
Object lbl_westPanel;
#Override
public void mouseClicked(MouseEvent e) {
if(((JLabel)e.getSource()).getText().equals("Order Status")){
System.out.println("Order Status clicked");
};
if(((JLabel)e.getSource()).getText().equals("Technical Documentation")){
System.out.println("Technical Documentation clicked");
};
if(((JLabel)e.getSource()).getText().equals("Check Report")){
System.out.println("Check Report clicked");
};
}
#Override
public void mouseEntered(MouseEvent e) {
lbl_westPanel = e.getSource();
((JComponent) lbl_westPanel).setFont(new Font("tahoma", Font.BOLD, 12));
}
#Override
public void mouseExited(MouseEvent e) {
lbl_westPanel = e.getSource();
((JComponent) lbl_westPanel).setFont(new Font("tahoma", Font.PLAIN, 11));
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
}
sure this is not the best way but may be useful for your problem
public class MyLabel extends JLabel implements MouseListener {
public MyLabel() {
addMouseListener(this);
}
public MyLabel(String txt) {
super(txt);
addMouseListener(this);
}
public void mouseClicked(MouseEvent e) {
System.out.println(getText() + " clicked");
}
public void mouseEntered(MouseEvent e) {
setFont(new Font("tahoma", Font.BOLD, 12));
}
public void mouseExited(MouseEvent e) {
setFont(new Font("tahoma", Font.PLAIN, 11));
}
public void mousePressed(MouseEvent e) { }
public void mouseReleased(MouseEvent e) { }
}
then
JLabel lbl_orderStatus = new MyLabel("Order Status");
JLabel lbl_technicalDocu = new MyLabel("Technical Documentation");
JLabel lbl_checkReport = new MyLabel("Check Report");
// MouseListenerBoldFont mouseListenerLabelBoldPlain = new MouseListenerBoldFont();
//
// lbl_orderStatus.addMouseListener(mouseListenerLabelBoldPlain);
// lbl_technicalDocu.addMouseListener(mouseListenerLabelBoldPlain);
// lbl_checkReport.addMouseListener(mouseListenerLabelBoldPlain);
My recommendation is to write inline (anonymous-class) handlers that forward the actual handling to another, non-anonymous function. This would give you something like:
JLabel lblOrderStatus = new JLabel("Order Status");
lblOrderStatus.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent evt) {
doWhateverClickOnOrderStatusRequires();
}
});
// much later
private void doWhateverClickOnOrderStatusRequires() { ... }
The name of the external not-quite-handler method (doWhateverClickOnOrderStatusRequires) should capture the task that it attempts to achieve (for example, launchRockets); and with this pattern, you can call the same not-quite-handler method from multiple handlers. Since the compiler will check that the calls are valid a compile-time, there are no fragile string-constants involved.
You probably still want to use a class which extends MouseAdapter, since it can be used as a MouseListener, a MouseMotionListener, and a MouseWheelListener all at once (You just have to add it as all of those into a component). I'm not sure why you need to get the text on a JLabel to detect if it's the one that has been clicked. You should create a class which extends MouseAdapter and make it solely for JLabels, then add it to that JLabel. You should define a custom constructor if you want that takes a JLabel for an argument so that it will automatically know what JLabel is being interacted with. You can then add a method which passes an event to the main class.
I'm getting stuck while building a forum like application which has a vote button.
I have vote up and vote down button for each content which are automatically generated. I want this button to only display the up and down arrow but not any text or label.. how can i find out which button is pressed?
Automated content..
ImageIcon upvote = new ImageIcon(getClass().getResource("vote_up.png"));
ImageIcon downvote = new ImageIcon(getClass().getResource("vote_down.png"));
JButton vote_up = new JButton(upvote);
JButton vote_down = new JButton(downvote);
vote_up.addActionListener(voting);
vote_down.addActionListener(voting);
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
//What to do here to find out which button is pressed?
}
};
any help is appreciated.
public void a(){
int crt_cnt = 0;
for(ClassA temp : listofClassA)
{
b(crt_cnt);
crt_cnt++;
}
}
public void b(crt_cnt){
//draw button
}
As from above, I have multiple vote_up and vote_down button created by the b function, how can i differentiate which crt_cnt is the button from?
There are multiple ways you might achieve this
You could...
Simply use the source of the ActionEvent
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if (e.getSource() == vote_up) {
//...
} else if (...) {
//...
}
}
};
This might be okay if you have a reference to the original buttons
You could...
Assign a actionCommand to each button
JButton vote_up = new JButton(upvote);
vote_up.setActionCommand("vote.up");
JButton vote_down = new JButton(downvote);
vote_down .setActionCommand("vote.down");
//...
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if ("vote.up".equals(e.getActionCommand())) {
//...
} else if (...) {
//...
}
}
};
You could...
Take full advantage of the Action API and make indiviual, self contained actions for each button...
public class VoteUpAction extends AbstractAction {
public VoteUpAction() {
putValue(SMALL_ICON, new ImageIcon(getClass().getResource("vote_up.png")));
}
#Override
public void actionPerformed(ActionEvent e) {
// Specific action for up vote
}
}
Then you could simply use
JButton vote_up = new JButton(new VoteUpAction());
//...
Which will configure the button according to the properties of the Action and will trigger it's actionPerformed method when the button is triggered. This way, you know 100% what you should/need to do when the actionPerformed method is called, without any doubts.
Have a closer look at How to Use Actions for more details
You can detect by using the method getSource() of your EventAction
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if (e.getSource() == vote_up ) {
// vote up clicked
} else if (e.getSource() == vote_down){
// vote down clicked
}
}
};
hey thanks for all the help and assistance! I've finally got it! I solved it by
assigning a text on the button, +/- for vote up or down, followed by the content id which i required, then change the font size to 0
vote.setText("+"+thistopic.content.get(crt_cnt).get_id());
vote.setFont(heading.getFont().deriveFont(0.0f));
after that i could easily trace which button is pressed by comparing to the
actionEvent.getActionCommand()
which return the text on the button!
I would wrap the JButton similar to this:
JButton createMyButton(final JPanel panel, final String text,
final boolean upOrDown, final int gridx, final int gridy) {
final JButton button = new JButton();
button.setPreferredSize(new Dimension(80, 50));
final GridBagConstraints gbc = Factories.createGridBagConstraints(gridx,
gridy);
panel.add(button, gbc);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
myActionPerformed(text, upOrDown);
}
});
return button;
}
You could use an int instead of the text, if more convenient.
I am programming my first complex application in Java, Swing. When I have added ActionListener to my JButton.
ActionListener changeButton = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e){
if(startButton.getText() == "Spustit") {
startButton.setText("STOP");
} else {
startButton.setText("Spustit");
}
}
}
I am adding ActionListener to the button itself
private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {
startButton.addActionListener(changeButton);
}
Can you tell me where I coded ActionListener badly?
Thanks to all!
You have coded the ActionListener good enough to be working, at least, for the action listener itself. The problem is that you are adding the action listener after an event (your second sample), thus your action listener will get called the second time you will click it.
A solution is very simple:
JButton button = new JButton();
button.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//...
}
});
Now the action listener should activate on the first click if you directly add a new ActionListener to the button, not after an action is performed
Why are you adding the actionlistener in actionPerformed? I think you should do something like this:
public static void main(String[] args) {
final JButton startButton = new JButton("Spustit");
ActionListener changeButton = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (startButton.getText() == "Spustit") {
startButton.setText("STOP");
} else {
startButton.setText("Spustit");
}
}
};
startButton.addActionListener(changeButton);
// Add it to your panel where you want int
}
I needed a JButton with an attached dropdown style menu. So I took a JPopupMenu and attached it to the JButton in the way you can see in the code below. What it needs to do is this:
show the popup when clicked
hide it if clicked a second time
hide it if an item is selected in the popup
hide it if the user clicks somewhere else in the screen
These 4 things work, but because of the boolean flag I'm using, if the user clicks somewhere else or selects an item, I have to click twice on the button before it shows up again. That's why I tried to add a FocusListener (which is absolutely not responding) to fix that and set the flag false in these cases.
EDIT: Last attempt in an answer post...
Here are the listeners: (It's in a class extending JButton, so the second listener is on the JButton.)
// Show popup on left click.
menu.addFocusListener(new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
System.out.println("LOST FOCUS");
isShowingPopup = false;
}
#Override
public void focusGained(FocusEvent e) {
System.out.println("GAINED FOCUS");
}
});
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("isShowingPopup: " + isShowingPopup);
if (isShowingPopup) {
isShowingPopup = false;
} else {
Component c = (Component) e.getSource();
menu.show(c, -1, c.getHeight());
isShowingPopup = true;
}
}
});
I've been fighting with this for way too long now. If someone can give me a clue about what's wrong with this, it would be great!
Thanks!
Code:
public class Button extends JButton {
// Icon.
private static final ImageIcon ARROW_SOUTH = new ImageIcon("ArrowSouth.png");
// Unit popup menu.
private final JPopupMenu menu;
// Is the popup showing or not?
private boolean isShowingPopup = false;
public Button(int height) {
super(ARROW_SOUTH);
menu = new JPopupMenu(); // menu is populated somewhere else
// FocusListener on the JPopupMenu
menu.addFocusListener(new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
System.out.println("LOST FOCUS");
isShowingPopup = false;
}
#Override
public void focusGained(FocusEvent e) {
System.out.println("GAINED FOCUS");
}
});
// ComponentListener on the JPopupMenu
menu.addComponentListener(new ComponentListener() {
#Override
public void componentShown(ComponentEvent e) {
System.out.println("SHOWN");
}
#Override
public void componentResized(ComponentEvent e) {
System.out.println("RESIZED");
}
#Override
public void componentMoved(ComponentEvent e) {
System.out.println("MOVED");
}
#Override
public void componentHidden(ComponentEvent e) {
System.out.println("HIDDEN");
}
});
// ActionListener on the JButton
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("isShowingPopup: " + isShowingPopup);
if (isShowingPopup) {
menu.requestFocus();
isShowingPopup = false;
} else {
Component c = (Component) e.getSource();
menu.show(c, -1, c.getHeight());
isShowingPopup = true;
}
}
});
// Skip when navigating with TAB.
setFocusable(true); // Was false first and should be false in the end.
menu.setFocusable(true);
}
}
Here's a variant of Amber Shah's "big hack" suggestion I just made. Without the isShowingPopup flag...
It's not bulletproof, but it works quite well until someone comes in with an incredibly slow click to close the popup (or a very fast second click to reopen it...).
public class Button extends JButton {
// Icon.
private static final ImageIcon ARROW_SOUTH = new ImageIcon("ArrowSouth.png");
// Popup menu.
private final JPopupMenu menu;
// Last time the popup closed.
private long timeLastShown = 0;
public Button(int height) {
super(ARROW_SOUTH);
menu = new JPopupMenu(); // Populated somewhere else.
// Show and hide popup on left click.
menu.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
timeLastShown = System.currentTimeMillis();
}
#Override public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {}
#Override public void popupMenuCanceled(PopupMenuEvent arg0) {}
});
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if ((System.currentTimeMillis() - timeLastShown) > 300) {
Component c = (Component) e.getSource();
menu.show(c, -1, c.getHeight());
}
}
});
// Skip when navigating with TAB.
setFocusable(false);
}
}
As I said in comments, that's not the most elegant solution, but it's horribly simple and it works in 98% of the cases.
Open to suggestions!
Here is another approach which is not too bad of a hack, if not elegant, and which, as far as I could tell, works. First, at the very top, I added a second boolean called showPopup.
The FocusListener has to be as follows:
menu.addFocusListener(new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
System.out.println("LOST FOCUS");
isShowingPopup = false;
}
#Override
public void focusGained(FocusEvent e) {
System.out.println("GAINED FOCUS");
isShowingPopup = true;
}
});
The isShowingPopup boolean does not get changed anywhere else--if it gains focus, it assumes it's shown and if it loses focus, it assumes it isn't.
Next, the ActionListener on the button is different:
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("isShowingPopup: " + isShowingPopup);
if (showPopup) {
Component c = (Component) e.getSource();
menu.show(c, -1, c.getHeight());
menu.requestFocus();
} else {
showPopup = true;
}
}
});
Now comes the really new bit. It's a MouseListener on the button:
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
System.out.println("ispopup?: " + isShowingPopup);
if (isShowingPopup) {
showPopup = false;
}
}
#Override
public void mouseReleased(MouseEvent e) {
showPopup = true;
}
});
Basically, mousePressed gets called before the menu loses focus, so isShowingPopup reflects whether the popup was shown before the button is pressed. Then, if the menu was there, we just set showPopup to false, so that the actionPerformed method does not show the menu once it gets called (after the mouse is let go).
This behaved as expected in every case but one: if the menu was showing and the user pressed the mouse on the button but released it outside of it, actionPerformed was never called. This meant that showPopup remained false and the menu was not shown the next time the button was pressed. To fix this, the mouseReleased method resets showPopup. The mouseReleased method gets called after actionPerformed, as far as I can tell.
I played around with the resulting button for a bit, doing all the things I could think of to the button, and it worked as expected. However, I am not 100% sure that the events will always happen in the same order.
Ultimately, I think this is, at least, worth trying.
You could use the JPopupMenu.isVisible() instead of your Boolean variable to check the current state of the popup menu.
Have you tried adding a ComponentListener to the JPopupMenu, so that you know when it's been shown and hidden (and update your isShowingPopup flag accordingly)? I'm not sure listening for focus changes is necessarily the right approach.
What you need is a PopupMenuListener:
menu.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent arg0) {
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent arg0) {
System.out.println("MENU INVIS");
isShowingPopup = false;
}
#Override
public void popupMenuCanceled(PopupMenuEvent arg0) {
System.out.println("MENU CANCELLED");
isShowingPopup = false;
}
});
I inserted this into your code and verified that it works.
Well, I can't be sure without seeing all of your code, but is it possible that the popup never actually gets focus at all? I've had problems with things' not getting focus properly in Swing before, so it could be the culprit. Try calling setFocusable(true) on the menu and then calling requestFocus() when you make the menu appear.
I tried the Answer of Tikhon Jelvis (introducing a smart combination of focusListener and mouseListener). It does not work for me on Linux (Java7/gtk). :-(
Reading http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#requestFocus%28%29 there is written "Note that the use of this method is discouraged because its behavior is platform dependent."
It may be that the order of listener calls changed with Java7 or it changes with GTK vs Windows. I would not recommend this solution if you want to be platform independent.
BTW: I created a new account on stackoverflow to give this hint. It seems I am not allowed to comment to his answer (because of reputation). But it seems I have a button to edit it. This stackoverflow is a very funny thing. :-)