MouseEntered event called for every nearby label - java

I am having issues while trying to make a highlighting 'label' that changes its icon, okay, so when MouseEntered event is being called for one jLabel, every nearby label's event is also being called and their icon is being changed. I've tried to disable that by using variable to deny changing other jLabel icons but it remains the same like it's being called at the same moment without letting the program storing values in variable and performing if checks, here's the code:
private int OverlayButton = -1;
private void jLabel1MouseEntered(java.awt.event.MouseEvent evt) {
SetButton( 1 );
}
private void jLabel1MouseExited(java.awt.event.MouseEvent evt) {
ResetButton( 1 );
}
private void jLabel2MouseEntered(java.awt.event.MouseEvent evt) {
SetButton( 2 );
}
private void jLabel2MouseExited(java.awt.event.MouseEvent evt) {
ResetButton( 2 );
}
private void jLabel3MouseEntered(java.awt.event.MouseEvent evt) {
SetButton( 3 );
}
private void jLabel3MouseExited(java.awt.event.MouseEvent evt) {
ResetButton( 3 );
}
public void SetButton( int button ) {
if( OverlayButton == -1 ) {
OverlayButton = button;
System.out.println( "SetButton method | (BUTTON-ID:"+ button+ ") ." );
switch( button ) {
case 1: {
jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Agendicus/SecondaryCalendar.png")));
}
case 2: {
jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Agendicus/SecondaryNotification.png")));
}
case 3: {
jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Agendicus/medal (1).png")));
}
case 4: {
}
}
}
else {}
}
public void ResetButton( int button ) {
if( OverlayButton != -1 ) {
switch( button ) {
case 1: {
jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Agendicus/calendar-with-a-clock-time-tools.png")));
}
case 2: {
jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Agendicus/notifications-button.png")));
}
case 3: {
jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Agendicus/medal (2).png")));
}
}
System.out.println( "ResetButton method | (BUTTON-ID:"+ button+ ") | Setting OverlayButton to -1." );
OverlayButton = -1;
}
}
I've also tried using resetting icons under each event for different jLabels, but unsuccessfuly.

Add break in your case my friend.. Add break.
case 1: {
jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Agendicus/SecondaryCalendar.png")));
break;
}
case 2: {
jLabel2.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Agendicus/SecondaryNotification.png")));
break;
}
case 3: {
jLabel3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Agendicus/medal (1).png")));
break;
}
Omitting the break statement cause each subsequent case to be executed.
For posterity, I want to point that the the switch statement was unnecessary and therefore the error you encountered was completely avoidable. Had you used, for one example, a custom class that implements MouseListener and takes the icon paths you wish to transition between as arguments your code would have been easier for others to follow when you have questions and need help. Here's an example that eliminates the source of your problem.
public static class LabelListener implements MouseListener {
private ImageIcon newIcon;
private ImageIcon defaultIcon;
private JLabel label;
public LabelListener(JLabel label, String newIconPath, String defaultIconPath) throws IOException{
this.label = label;
this.label.setSize(100, 100);
this.newIcon = new ImageIcon(newIconPath);
this.defaultIcon = new ImageIcon(defaultIconPath);
this.label.setIcon(this.defaultIcon);
}
#Override
public void mouseEntered(MouseEvent evt){
this.label.setIcon(this.newIcon);
}
#Override
public void mouseExited(MouseEvent evt){
this.label.setIcon(this.defaultIcon);
}
#Override
public void mousePressed(MouseEvent evt){
}
#Override
public void mouseClicked(MouseEvent evt){
}
#Override
public void mouseReleased(MouseEvent evt){
}
}
Good that you have written the correct way of implementing the listener. However the problem that he had in his code is of not using break. If you are using switch-case, you need to use break. I think it is just a miss.

Related

update index of combobox when user selects a different index than listed from a swing GUI form?

when selecting different option in a combobox the index does not change and will always default to the already selected difficulty
public class ClickingGame extends javax.swing.JFrame {
int difficulty;
public int diffRec() {
// diff = difficulty;
switch (comboDifficulty.getSelectedIndex()) {
case 0:
difficulty = 0;
break;
case 1:
difficulty = 1;
break;
case 2:
difficulty = 2;
break;
default:
break;
}
return (difficulty);
}
public ClickingGame() {
initComponents();
}
private void comboDifficultyActionPerformed(java.awt.event.ActionEvent evt) {
}
You need to add the ActionListener to the ComboBox, wich is calling the diffRec method (to update the selected difficulty). Like so:
comboDifficulty.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
diffRec();
}
});
Your code snippet does not show all relevent parts, so please check
the answer and tell me if it solves your problem.

Replace many "else if" with something else

I am using an ActionListener and have lots of else if statements in order to know which button is pressed and run some code depending on the button.
Is there a way to make the code nicer? I have nearly 10 else if statements following each other, is there something else I could use instead?
Sample of code:
class BtnListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == menu.getOpen()) {
getFile();
} else if (e.getSource() == btnPlay) {
} else if (e.getSource() == btnQuit)) {
}
}
Thanks.
You can fill Map<Object, Consumer<ActionEvent>> before using of listener, for example in constructor, where key is source and value is a consumer for action event. In action perform just get consumer by key and invoke it.
class BtnListener implements ActionListener {
Map<Object, Consumer<ActionEvent>> eventsMap = new HashMap<>();
public BtnListener() {
eventsMap.put(menu.getOpen(), actionEvent -> this.getFile());
eventsMap.put(btnPlay, actionEvent -> { //do something
});
eventsMap.put(btnQuit, actionEvent -> { //do something else
});
}
#Override
public void actionPerformed(ActionEvent e) {
Optional.of(e)
.map(ActionEvent::getSource)
.map(eventsMap::get)
.ifPresent(
actionEventConsumer -> actionEventConsumer.accept(e)
);
}
}
You may use the action command of the button, and a switch-case block :
public void actionPerformed(ActionEvent e){
switch(e.getActionCommand()) {
case "Open":
open();
break;
case "Delete":
delete();
break;
default :
break;
}
}
Of course you will have to set the action command of each button first, like :
openButton.setActionCommand("Open");
Note that switch-case with String objects only exists since JDK 7 : Strings in switch Statements
You can switch statement instead lot of else if ladder.
class BtnListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == menu.getOpen()) {
getFile();
}
switch( e.getSource() ){
case btnPlay:
break;
case btnQuit:
break;
default:
}
}
}
the best way to avoid all the "overheads" is to Lambda-Expressioned the buttons. Example:
JButton b1 = new JButton("Play");
b1.addActionListener(e -> play());
...
JButton bn = new JButton("Stop");
bn.addActionListener(e -> stop());
...
private void play() {
....// playing codes
}
...
private void stop() {
...// stopping codes
}
...

Java Swing buttongroup clear on click

i have one button group with 2 radio buttons:
private javax.swing.JRadioButton jRadioButtonESPRINCIPAL;
private javax.swing.JRadioButton jRadioButtonESSECUNDARIO;
buttonGroup1 = new javax.swing.ButtonGroup();
I know that i can clear the group by buttonGroup1.clearSelection(), but i want to do this only if i click on a clicked radio button.
I have tried
private void jRadioButtonESPRINCIPALMouseClicked(java.awt.event.MouseEvent evt) {
if (jRadioButtonESPRINCIPAL.isSelected()) {
buttonGroup1.clearSelection();
}
else{
jRadioButtonESPRINCIPAL.setSelected(true);
}
}
private void jRadioButtonESSECUNDARIOMouseClicked(java.awt.event.MouseEvent evt) {
if (jRadioButtonESSECUNDARIO.isSelected()) {
buttonGroup1.clearSelection();
}
else{
jRadioButtonESSECUNDARIO.setSelected(true);
}
}
But didnt works
Any help will be appreciate
My previous answer was wrong sorry. You have to use ActionListeners like this:
jRadioButtonESPRINCIPAL.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
//your code goes here
}
});
and then use a variable to store the last RadioButton that was selected. In the ActionListener you then have to check if the isSelected() equals the last selection. If yes, then use buttonGroup1.clearSelection();.
So the final code should look like this:
jRadioButtonESPRINCIPAL.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (jRadioButtonESPRINCIPAL.equals(lastSelectedRadioButton)) {
buttonGroup1.clearSelection();
lastSelectedRadioButton = null;
}
else {
lastSelectedRadioButton = jRadioButtonESPRINCIPAL;
}
}
});
jRadioButtonESSECUNDARIO.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (jRadioButtonESSECUNDARIO.equals(lastSelectedRadioButton)) {
buttonGroup1.clearSelection();
lastSelectedRadioButton = null;
}
else {
lastSelectedRadioButton = jRadioButtonESSECUNDARIO;
}
}
});

basic boolean states problems

I am trying to write a piece of code so that when a key is pressed it will execute something, but then the key will have to be released and then repressed again in order to retrigger the event. So if the user just holds down the key, it wont keep doing it over and over, instead they will have to press and release repeatedly.
So far, I have:
if(keyLifted)
{
if(Keyboard.isKeyDown(45))
{
keyLifted = false;
dostuff;
}
else if(Keyboard.isKeyDown(46))
{
keyLifted = false;
dostuff();
}
else
{
keyLifted = true;
}
}
but this is flawed for obvious reasons (it will only reset the key to being unlifted if the key is already lifted: if the key was pressed, it wont be set to unpressed). I have tried a couple variations, but I just cant get it to work.
Thanks in advance for any help!
You should use a KeyListener to capture keyboard events. Here you go:
public class KeyListenerExample extends JFrame {
public KeyListenerExample() {
addKeyListener(new KeyAdapter() {
private boolean keyLifted;
public void keyReleased(KeyEvent e) {
keyLifted = true;
}
public void keyPressed(KeyEvent e) {
keyLifted = false;
switch (e.getKeyChar()) {
case 45:
doStuff();
break;
case 46:
doStuff();
break;
}
}
});
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void doStuff() {
System.out.println("stuff");
}
/**
* #param args
*/
public static void main(String[] args) {
new KeyListenerExample();
}
}
I just kept the keyLifted because it is in your example. But I think for the usual keyboard stuff you don't need it.

Swing GUI not updating

I'm writing an application that reads in audio, analyses this data and then displays the results in realtime. Currently I am using a SwingWorker to run the loop that initiates the background analysis and calling the SwingUtilities.invokeLater method inside the loop to update the GUI components each time analysis has completed. At the moment, the GUI seems to be updating randomly, and occasionally not at all.
The following code shows how I'm trying to accomplish this. The TunerListener is an inner class of a JPanel subclass. PrevNote, nextNote, frequency, and the light variables are all components in the JPanel subclass that I want to update:
private class TunerListener implements ActionListener {
private boolean firstUpdate = true;
private boolean executing = false;
private TunerWorker tunerWorker = null;
private final class TunerWorker extends SwingWorker<Void, Void> {
#Override
protected Void doInBackground() {
while (!this.isCancelled()) {
// Audio analysis in worker thread
model.update(firstUpdate);
// Update components in EDT
if (!this.isCancelled()) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
prevNote.setText(model.getPrev());
currentNote.setText(model.getNote());
nextNote.setText(model.getNext());
frequency.setText("Frequency: "
+ model.getFrequency());
switch (model.getOffset()) {
case -2:
light_2.setIcon(onRed);
light_1.setIcon(off);
light0.setIcon(offBig);
light1.setIcon(off);
light2.setIcon(off);
break;
case -1:
light_2.setIcon(off);
light_1.setIcon(onRed);
light0.setIcon(offBig);
light1.setIcon(off);
light2.setIcon(off);
break;
case 0:
light_2.setIcon(off);
light_1.setIcon(off);
light0.setIcon(onGreen);
light1.setIcon(off);
light2.setIcon(off);
break;
case 1:
light_2.setIcon(off);
light_1.setIcon(off);
light0.setIcon(offBig);
light1.setIcon(onRed);
light2.setIcon(off);
break;
case 2:
light_2.setIcon(off);
light_1.setIcon(off);
light0.setIcon(offBig);
light1.setIcon(off);
light2.setIcon(onRed);
break;
}
firstUpdate = false;
}
});
}
}
return null;
}
#Override
protected void done() {
}
};
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getActionCommand().equals("tune")) {
if (!executing) {
executing = true;
firstUpdate = true;
tune.setText("Stop Tuning");
tunerWorker = new TunerWorker();
tunerWorker.execute();
} else {
tune.setText("Start Tuning");
executing = false;
tunerWorker.cancel(true);
}
}
}
}
Edit
I notice when I use the debugger that I sometimes get to a point where it tells me the source could not be found and in the debugging window it says something about a FutureTask$Sync.innerRun. Does this narrow it down at all?
As an alternative, use an instance of javax.swing.Timer, illustrated here, to Start and Stop the playing of a selected Note, shown here. The play() method feeds a SourceDataLine, which operates asynchronously, and the enum Note makes constructing a JComboBox particularly easy.
final JComboBox combo = new JComboBox();
for (Note note : Note.values()) {
combo.addItem(note);
}
combo.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println(combo.getSelectedItem());
}
});
this.add(combo);

Categories