JTabbedPane how to determine that user left tab? - java

I wonder, if it possible to determine, that user left certain tab. For example, we have 2 tabs: "omg" and "lol". The current tab is omg. I want to know that user switched from "omg" to "lol"

By adding a change listener to the JTabbedPane you will know when the tab selection changes.
Updated: Added tab index tracking
tabbedPane.getModel().addChangeListener(new ChangeListener() {
int lastTabIndex = -1;
public void stateChanged(ChangeEvent e) {
int newIndex = tabbedPane.getSelectedIndex();
if (lastTabIndex == 1 && newIndex == 2) { //or whatever check/combination of checks you would like
//switched from tab 1 to tab 2!
}
//or just check for leaving tab 1
if (lastTabIndex == 1) {
//left tab 1!
}
//etc
lastTabIndex = newIndex;
}
});

I don't have the source I used for this, but I'm pretty sure what I did was extend JTabbedPane and override setSelectedIndex(int). It is called when the index is GOING to be changed to the indicated number, and I used it to validate things on the pane that was going to be left. If your logic does not execute super.setSelectedIndex(int), then you don't leave the pane (which is what I was after).

Related

How to get previous jTabbedPane overlap

I have problem with getting id of previous overlap of jTabbedPane.
ksiegiWieczysteTabbedPane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
KsiegaWieczystaPanel księgaWieczystaPanel = (KsiegaWieczystaPanel) ksiegiWieczysteTabbedPane.getSelectedComponent();
if(MainApp.main.showPytanieBox("Czy chcesz zapisać zmiany?")) {
if(księgaWieczystaPanel != null) {
księgaWieczystaPanel.zapiszWszystko();
}
}
}
});
Now I can get the actual clicked overlap but do I have chance to get the previous one? Assume I have 3 overlaps: A,B,C. Now if I click A it is easy to recognize that it is A by ksiegiWieczysteTabbedPane.getSelectedComponent() but when I click B is it possible to know that the previous overlap which was selected were A?
as far as i know this is how to set and get selected index in jtabbedPane
JTabbedPane pane = new JTabbedPane();
// this represents previously selected tab.
int selectedIndex = pane.getSelectedIndex();
//with this method you can change the selected index.
pane.setSelectedIndex(yourIndex);

doClick(), and Simon: All buttons will unpress at the same time instead of individually

Hi I'm new to stackoverflow so bear with me if I make mistakes.
I'm making this Java Simon Says Game for a class project. It works by a random number generator for each sequence#. I show the sequence through doClick() but remove the actionlisteners beforehand and add it afterwards.
The problem is the buttons won't unpress or unarm until all other buttons have been pressed. I've tried using thread.sleep to put a delay between each if...else statements yet it only stays pressed for longer. I've tried updating the gui through repaint(), revalidate(), updateUI() within the try... catch of the thread.sleep but that didn't work either.
I've realized this issue is mainly cosmetic because when I tried implementing setPressed or setArmed it said it wasn't being pressed but it looked pressed.
Here is the code snippet in it's most simplest form without thread.sleep or my previous attempts in comments.
public void sequence2() //This is where the issue happens. The buttons won't unpress until every button has been pressed.
{
level.setText(" Level 2"); //Level indicator
Green.removeActionListener(Listener);
Red.removeActionListener(Listener);
Yellow.removeActionListener(Listener);
Blue.removeActionListener(Listener);
if(sequence1 == 1)
{
Green.doClick(300); //Programmatically clicks the button
}
else if(sequence1 == 2)
{
Red.doClick(300);
}
else if(sequence1 == 3)
{
Yellow.doClick(300);
}
else if(sequence1 == 4)
{
Blue.doClick(300);
}
if(sequence2 == 1)
{
Green.doClick(300);
}
else if(sequence2 == 2)
{
Red.doClick(300);
}
else if(sequence2 == 3)
{
Yellow.doClick(300);
}
else if(sequence2 == 4)
{
Blue.doClick(300);
}
Green.addActionListener(Listener);
Red.addActionListener(Listener);
Yellow.addActionListener(Listener);
Blue.addActionListener(Listener);
}
I'm very new to java so I'm not skilled in multithreading or working on the Event Dispatch Thread for that manner. But if that's the only solution I'll need some more help with that.
I have the full code in a zip file with previous attempts commented out if that will help.
https://drive.google.com/file/d/0Bxg4WleC9jD2VFhoZmZBNjV6Vkk/view?usp=sharing
Invoking doClick() may be an awkward choice for this, as it uses a Timer internally. Instead, use a JToggleButton, which will allow you to control each button's appearance based on its selected state using setSelected(). A complete example is shown in the game Buttons. In the ActionListener of your Swing Timer, select the current button, play its note and increment the sequence index. When all notes have been played, unselect all the buttons.
Addendum: Can you show how you implement the timer?
In outline, given a suitable list of toggle buttons:
private static final int MAX = 4;
List<JToggleButton> buttons = new ArrayList<JToggleButton>(MAX);
private int i;
The timer's listener might look like this:
#Override
public void actionPerformed(ActionEvent e) {
Object src = e.getSource();
JToggleButton b = buttons.get(i);
if (i > MAX) { // reset i and all the buttons
for (JToggleButton b : buttons) {
b.setSelected(false);
}
timer.stop();
i = 0;
} else {
b.setSelected(true);
// play tone i
i++;
}
}
A toggle button's item listener should update the button's appearance as indicated by its state:
#Override
public void itemStateChanged(ItemEvent e) {
JToggleButton b = (JToggleButton) e.getItem();
if (b.isSelected()) {
// change icon, color etc.
} else {
// restore icon, color etc.
}
}

Get associated mouse click from ExpandTree event in SWT

I'm trying to stop the tree from collapsing or expanding when the user double clicks a column on a tree. It should only be allowed if the user clicks on the first column.
See, if a user double clicks the checkbox on node2 world1, the tree expands or collapses. I don't want that to happen. My tree needs SWT.FULL_SELECTION to detect the clicks on each of the columns, so that's not the way to go.
My listener looks like this
tree.addTreeListener(new TreeListener() {
#Override
public void treeExpanded(TreeEvent e) {
TreeItem parent = (TreeItem) e.item;
Point p = new Point (e.x, e.y);
int column = CheckboxClickListener.getColumn(p,parent);
if (column > 0) {
e.doit = false;
}
}
#Override
public void treeCollapsed(TreeEvent e) {
TreeItem parent = (TreeItem) e.item;
Point p = new Point (e.x, e.y);
int column = CheckboxClickListener.getColumn(p,parent);
if (column != 0) {
e.doit = false;
}
}
});
Problem is, the mouse event that generated the click is not the same as the TreeEvent that expands the tree. Thus, the e.x and e.y are both zero, making my Point detection useless. Listening to the mouse event and maintaining the last x and y to check here in the TreeExpand event seems bug-prone since the user may also expand the tree using the keyboard (thus the x and y may not reflect the user action). I also considered adding a time constraint to check that but seems like a bad way to handle the issue.
How can I detect which mouse event triggered the expand event?
PS: e.doit=false does nothing, even outside the if condition, so help with stopping the tree from expanding/collapsing would be appreciated as well :)
Thank you!
I found someone saying this is a bug at this link http://www.eclipse.org/forums/index.php/t/257325/
The following code stops the tree from expanding on doubleclick but I'm not sure why or what are the side effects.
tree.addListener (SWT.MeasureItem, new Listener(){
#Override
public void handleEvent(Event event) {}
});
This stops the expanding when doubleclicking ANY column. Clicking on the small arrow at the left of the TreeItem still expands the tree (as it should).

ListSelectionEvent, firing an event when clicking the currently selected item in JList

Let 'x' be an item in the JList. When I click it for the first time, the event fires, when I click it again, the event does not fire. I have to click some other item and then come back to 'x'.
How can I fire the event repeatedly from 'x' without having to deal with other items.
This is my code:
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (list.getSelectedIndex() == -1) {} else {
String clicked = (String)list.getSelectedValue();
//method to fire is here
}
}
updateDisplays();
}
The ListSelectionListener reflects changes to the lists selection, you could use a MouseListener instead...
For example...
MouseListener ml = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent evt) {
if (SwingUtilities.isLeftMouseButton(evt) && evt.getClickCount() == 1) {
if (list.getSelectedIndex() != -1) {
int index = list.locationToIndex(evt.getPoint());
System.out.println("You clicked item # " + index);
}
}
}
}
list.addMouseListener(ml);
You can add a MouseListener and watch for clicks. Note that a click that changes the selection will fire both the MouseListener and your ListSelectionListener.
Another option is to immediately clear the selection from your ListSelectionListener; that way the next click will reselect and retrigger, although you will lose the ability to navigate through items with the keyboard.
It seems like sort of an unusual UX decision, though, to assign significance to a click on an already selected item in a list.
Adding based on your question comments: If you go the MouseListener route, I recommend looking for double-clicks instead of single-clicks if the click is going to execute an action (especially if the action changes data and is not undoable). Also note that your ListSelectionListener will execute actions as you navigate through the list with the keyboard, which may not be what you intend.
If your commands in your history list are typed, you could also consider using a drop-down combo box for both command entry and the history list, where a selection from history fills in the command text but does not execute. You'd also have an opportunity to add auto-complete from command history.

how to remove JMenu.addSeparator() after it is being called

Hello guys,
I just want to ask something if is it possible to remove JMenu.addSeparator() after it is being called? for example in my form there is a menu bar and inside the menu bar lets say there are three JmenuItems and each of it has JMenu.addSeparator(). What i want to do is, if a different user is log in I want to setVisible(false) one of JMenuItem because that particular user in not authorize to use that JMenuItem. The problem is when I setVisible(false) one of the JMenuItem the JMenu.addSeparator() still exist which kinda awkward to watch since there are no JMenuItem exist in the middle of two JMenu.addSeparator(). Hope you can help me with this problem.
Thanks in advance
You have two possible solutions...
You Could...
Remove the contents of the menu and rebuilt it based on what the user can do...
menu.removeAll();
// Add menu items back in...
// Personally, I'd have some method that could return back all
// the JMenuItems that could appear on this menu based on the
// the user...
This would be my preferred solution...
You Could...
Hide/show the menu items based on what the current user can actually do and then remove all the JSeparators that appear next to each other, for example...
Component last = null;
for (Component comp : menu.getComponents()) {
if (comp instanceof JSeparator && last instanceof JSeparator) {
menu.remove(comp);
} else {
last = comp;
}
}
Personally, I know which I would prefer and generally, which would produce consistent results...
I ran into a situation where I had to remove the separator from an existing menu. (Old code and wasn't allowed to refactor the whole mess.)
So I used the idea of MadProgrammer's 2nd solution - but rewrote it to actually work.
Component last = null;
for (int idx = 0; (idx < m_fileMenu.getMenuComponentCount()); idx++) {
Component comp = m_fileMenu.getMenuComponent(idx);
if (comp instanceof JPopupMenu.Separator && last instanceof JPopupMenu.Separator) {
m_fileMenu.remove(comp);
idx--;
} else {
last = comp;
}
}

Categories

Resources