Gridlayout and mouse listeners - java

hi i am trying to build a grid-layout GUI with mouse listener. SO when a particular cell is clicked in a grid ,information would be displayed. I don't know where to start, any help would be good
thankyou

I believe you have a class that inherits from JPanel or JFrame and there is whole GUI in it. Then, this class should implement mouseListener. Then your class should have similar code:
#override
public void mouseClicked(MouseEvent e){}
#override
public void mousePressed(MouseEvent e){}
#override
public void mouseEntered(MouseEvent e){}
#override
public void mouseReleased(MouseEvent e){
/*This method is being called when you release your click. It's better
then mouseClicked because mouseClicked is only called when you press
and release on the same pixel or Object (not sure about it)
*/
}
#override
public void mouseExiteded(MouseEvent e){}
In each method you can get source of
MouseEvent e
using
Object source = e.getSource();
if (source == button1){
//Do sth
}if (source == button2){
//Do sth else
}if (source == radioButton1){
//Do whatever you want
}
Then you have reference to the source, so you can modify what you want.

In your gridlayout, set all grids with some Component such as Button or Label. You can set listeners on the components added and display information when a component is clicked

To use properly a gridbaglayout, you should first work on the gridbagconstraints. Then, you should use the ActionListener interface to handle the mouse clicks. If the cells are of the type Labels, you coud hide the text by using myLabel.setText("") and putting the text by using myLabel.setText("information to display"). If you need more help, just ask :D and +1 if it helps ^^

Related

Adding MouseListeners for JToolBar (events are consumed?)

When adding a MouseListener to a JToolBar,
jToolbar.addMouseListener(new MouseInputAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
log.debug(e.getPoint());
}
});
The event only fires when clicked outside the JToolBar's gripper.
If I override BasicToolBarUI's createDockingListener():
#Override
protected MouseInputListener createDockingListener() {
return new MouseInputAdapter() {
#Override
public void mousePressed(MouseEvent evt) {
log.debug(e.getPoint());
}
}
}
The event will fire when clicked on the gripper.
So my question is, why? Is the MouseEvent consumed in the dockingListener? But I don't see any code that consumes the event.
The MouseEvent is being automatically consumed by the Container at a number of points for a number of different reasons (some relating to how the native peer needs to deal with the event)...
Most notably in the private method Container#processMouseEvent, but it could be consumed before then
This basically means, when you attach a MouseListener to any component, it will consume all mouse events going to any component (or part thereof) that it resides above.
Think of mouse events like rain. When a raindrop hits something, it stops.

mouseDragged not returning appropriate button down

How can I know the button that was pressed from within a mouseDragged event?
I'm having an issue in mouseDragged() because the received MouseEvent returns 0 for getButton(). I have no problem with the mouse location, or even detecting mouse clicks. The mouseClicked() event returns the appropriate button for getButton().
Any suggestions on how I can do this? I assume I could do a work-around using mouseClicked, or mousePressed, but I would prefer to keep this all within mouseDragged.
Thanks for your time and answers.
As pointed out in comments and other answers, SwingUtilities provides three methods for cases like this, which should work for all MouseEvents:
SwingUtilities.isLeftMouseButton(aMouseEvent);
SwingUtilities.isRightMouseButton(aMouseEvent);
SwingUtilities.isMiddleMouseButton(aMouseEvent);
As for what the problem with your approach is, the javadoc of getButton() says:
Returns which, if any, of the mouse buttons has changed state.
Since the state of the button doesn't change while it is being held down, getButton() will usually return NO_BUTTON in mouseDragged. To check the state of buttons and modifiers like Ctrl, Alt, etc. in mouseDragged, you can use getModifiersEx(). As an example, the below code checks that BUTTON1 is down but BUTTON2 is not:
int b1 = MouseEvent.BUTTON1_DOWN_MASK;
int b2 = MouseEvent.BUTTON2_DOWN_MASK;
if ((e.getModifiersEx() & (b1 | b2)) == b1) {
// ...
}
Jacob's right that getButton() doesn't get you the button by design. However, I found a cleaner solution than bit operations on getModifiersEx(), that you can also use within mouseDragged:
if (SwingUtilities.isLeftMouseButton(theMouseEvent)) {
//do something
}
Similar methods exist for the middle button and the right button.
int currentMouseButton = -1;
#Override
public void mousePressed(MouseEvent e) {
currentMouseButton = e.getButton();
}
#Override
public void mouseReleased(MouseEvent e) {
currentMouseButton = -1;
}
#Override
public void mouseDragged(MouseEvent e) {
if (currentMouseButton == 3) {
System.out.println("right button");
}
}
This could be possibly a problem of your java sandbox.
The following code works well all the time (almost, as you can see).
#Override
public void mouseDragged(MouseEvent e) {
e.getButton();
}
Please try your code on a different machine.

Removing MouseListener when something happens

In the game that I'm currently making I have three different mousePressed methods, one for single fire, one for automatic fire and one for melee attacks. Because the one for automatic fire uses a swing Timer I can override it in the other mousePressed methods by using timer.stop(); in them.
But the single fire mousePressed calls the fire() method directly so I can't override it in any way from the other mousePressed. The code below shows the method for the fireing (bullet is a ArrayList).
public void fire(){
if(!power.getChainsaw()){
bullet.add(new Bullet(x, y));
}
}
When the player gets a melee weapon I therefor need to remove the MouseListener for the single fireing. I have tried the code below but it didn't work.
removeMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
player.mousePressed2(e);
}
)};
I add the single fire and melee MouseListener in the exact same way as this. This is hwo the acctual mousePressed methods lok like.
public void mousePressed2(MouseEvent e){
if(SwingUtilities.isLeftMouseButton(e)){
timer.stop();
fire();
}
}
public void mousePressed3(MouseEvent e){
if(SwingUtilities.isLeftMouseButton(e)){
timer.stop();
}
}
mousePressed2 is the single fire method and mousePressed3 is the melee method
removeMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
player.mousePressed2(e);
}
)};
Look at what you are doing here. You are removing an instance of MouseAdapter created in place. This means that a new instance of mouse adapter will be created and then removed, but because the specific listener instance is not binded to any button, nothing will happen.
Pass the correct listener to the removeMouseListener method and it will work.
MouseAdapter myListener = new MouseAdapter() {
public void mousePressed(MouseEvent e){
player.mousePressed2(e);
}
};
someButton.addMouseListener(myListener);
// then when you want to remove it, use the same referenece.
someButton.removeMouseListener(myListener);

Java Swing default focus on frame

I am learning java and Swing right now and trying to develop simple programms for education purposes.
So here is the question.
I have gridlayout and fields on my frame with default text
accNumberField = new JTextField("0", 10);
accNumberField.addFocusListener(new FocusListener() {
int focusCounter = 0;
#Override
public void focusGained(FocusEvent arg0) {
// TODO Auto-generated method stub
if (focusCounter > 0)
accNumberField.setText("");
focusCounter++;
}
What I want is that when user click on field for the first time the default text is disappered. So I add focus listener and used accNumberField.setText(""); in focusGained method.
But the problem is that for default first field in my frame getting focus right in time of frame creation. And default text is disappearing from the begining. I used counter as you can see. But that's not what I wanted.
I want that no field would get focus in time of creation and every field would be able to get focus from the time when user would click on one of them.
Sorry if I spelled something wrong. English is not my native language.
Found a thread having a code example of your desired functionality, Java JTextField with input hint. Precisely, you need to provide your own implementation of JTextField which will be holding the "default-text" in a field, specially created for that.
For your second question, you can set the focus to some button or frame itself.
Is there any reason that you use focusListener()? why not use mouseListener() as follow?
accNumberField.addMouseListener(new MouseAdapter()
{
#Override
public void mouseReleased(MouseEvent e)
{
accNumberField.setText("");
}
});
if you want to clear the text for the first click, you can simply use a boolean:
//outside constructor
private boolean isTextCleared = false;
//in constructor
accNumberField.addMouseListener(new MouseAdapter()
{
#Override
public void mouseReleased(MouseEvent e)
{
if (!isTextCleared)
{
accNumberField.setText("");
isTextCleared = true;
}
}
});

JTable won't listen to Doubleclicks

I´m trying to implement an undo (and redo) function for an editable JTable with the default components. The JTable has an extra class to specify its properties called SpecifiedJTable.
To do so I wanted to grab the moment when a cell is doubleclicked (i.e. the moment when a cell is chosen/marked to be edited) to push the information in the cell and its coordinates onto the stack.
This should be done by a MouseListener ...at least that was my idea.
I tried this (standing in the constructor of my SpecifiedJTable class)
class JTableSpecified extends JTable {
private static final long serialVersionUID = 1L;
private int c; // the currently selected column
private int r; // the currently selected row
public JTableSpecified(String[][] obj, String[] columnNames) {
super(obj, columnNames); // constructs the real table
// makes that you can only select one row at a time
this.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
// makes that columns are not squeezed
this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// forbids to rearrange the columns
getTableHeader().setReorderingAllowed(false);
// adds action listener
this.getModel().addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
r = getSelectedRow();
c = getSelectedColumn();
// get the String at row r and column c
String s = (String) getValueAt(r, c);
if (jobDisplayed) jobSwitch(c, s);
else resSwitch(c, s);
}
});
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
System.out.println("test");
}
}
});
}
}
but somehow the clickCounter doesn´t want to reach anything that´s higher than 1.
I am glad about any answer and help. Thanks.
The problem you are experiencing is related to use of mouseClicked() rather than using mousePressed(). In this case it appears to be very hard to increase the click counter, yet still it is possible. It took me lots of clicking and also mouse movement to increase the click counter over 1. You could try it by yourself, in your code. To get the counter over 1 you need to go crazy on the mouse by pressing & releasing fast while moving the mouse from cell to cell at the same time (or maybe I was just luckily clicking between the cells?).
As you can see in this fully working sample, made from your code, two mouse presses, using the mousePressed() method are being detected just fine.
public class JTableSpecified extends JTable {
private static final long serialVersionUID = 1L;
public JTableSpecified(String[][] obj, String[] columnNames) {
super(obj, columnNames); // constructs the real table
// makes that you can only select one row at a time
this.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
// makes that columns are not squeezed
this.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
// forbids to rearrange the columns
getTableHeader().setReorderingAllowed(false);
// adds action listener
this.getModel().addTableModelListener(new TableModelListener() {
#Override
public void tableChanged(TableModelEvent e) {
}
});
this.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
if (e.getClickCount() == 2) {
System.out.println("test");
}
System.out.println("e.getClickCount() = " + e.getClickCount());
}
});
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JPanel panel = new JPanel();
panel.add(new JTableSpecified(new String[][]{{"oi", "oi2"}, {"oi3", "oi4"}}, new String[]{"Col1", "Col2"}));
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(panel);
f.pack();
f.setVisible(true);
}
});
}
}
Conclusion: Maybe you in fact want to use the mousePressed() method?
This answer extends Boro´s answer.
To catch every case that enables the user to edit the table I will also need to add a KeyListener for F2 (which has the same effect as double clicking onto a cell) and disable the automatic cell editing by pressing any key.
I just added it to the constructor right behind the mouseListener (see above)
// forbids the editing by striking a key
this.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
// keyListener to react on pressing F2 (key code 113)
this.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 113) System.out.println("test");
}
});
The BasicTableUI is responding to the double-click by going into an edit mode on the cell that was double-clicked. It does lots of complicated stuff, part of which involves creating a JTextField (or other component) to allow the data to be edited, and then preventing the mouse click event from propagating any further.
If your table, or that table cell, is not editable, you can easily capture mouse events with click count 2, 3, 4, .... But since you want your table to be editable, you need a different approach.
One idea would be to override JTable.editCellAt()
A better idea is to forget about messing with the JTable and instead listen for data changes on the table model itself.
the error in the code is that the mouseClicked method is called as soon as the first click takes place. when a double click takes place the mouseClicked method is called again. you can place a static variable (or a class variable) for the earlier click event storing the time (using the e.getWhen() method).
Check for the time difference and if it's small enough, execute your actions (I'd suggest calling a doubleClick method).
you may have to implement mouse listener in your class JTableSpecified since a static variable might not be placed in your existing code.

Categories