JTabbedPane is too efficient
Hi there,
Not sure if anyone is able to help me, and don抰 shout at me if I am trying to 搖ninvent?the wheel, but I have a problem with a JTabbedPane in that it is too efficient!
I would like to have control over switching panes, so as I can ask the user if they want to save changes before switching panes. I have extended ChangeListener to the Class and added a stateChangeMethod that does what I require, but only after the new pane has already loaded.
I found if I removed all references to ChangeListener the panes still switch? Ordinarily this would be great, but it is frustrating that when the question regarding saving changes is displayed, you can抰 see the changes referred to as the new pane has already loaded!
So basically my question is can I override the default functionality of the JTabbedPane to be triggered by my StateChanged method?
Thanks Coffee_Junkie
Hi thanks for the idea, but it is not really what I am looking for.
The Wizards you suggest appear to be linear, and I prefer the flexibility the JTabbedPane offers.
Basically what I would like in an ideal world is a way of overriding the default behaviour of the JTabbedPane Tabs so they do not switch when clicked on by a mouse.
Maybe I should cross my fingers rather than holding my breath on this one!!
Coffee_Junkie
Well, that's controlled by the L&F. Depending on the L&F it may be easier or harder to change.
public class MyTabbedPaneUI extends MetalTabbedPaneUI {
public MyTabbedPaneUI() {
}
protected MouseListener createMouseListener() {
return new MyMouseHandler();
}
/**
* This inner class is marked "public" due to a compiler bug.
* This class should be treated as a "protected" inner class.
* Instantiate it only within subclasses of BasicTabbedPaneUI.
*/
public class MyMouseHandler extends MouseAdapter {
public void mousePressed(MouseEvent e) {
if (!tabPane.isEnabled()) {
return;
}
int tabIndex = getTabAtLocation(e.getX(), e.getY());
if (tabIndex >= 0 && tabPane.isEnabledAt(tabIndex)) {
if (tabIndex == tabPane.getSelectedIndex()) {
if (tabPane.isRequestFocusEnabled()) {
tabPane.requestFocus();
tabPane.repaint(getTabBounds(tabPane, tabIndex));
}
} else {
try {
TabChangeListener t = (TabChangeListener)tabPane.getClientProperty("tabChangeListener");
if(t != null) {
t.tabWillChange(tabPane.getSelectedIndex(), tabIndex); // old, new
}
tabPane.setSelectedIndex(tabIndex);
} catch(PropertyVetoException(veto) {
// change not allowed...
}
}
}
}
}
}
// very early in your app, before creating the UI, do this:
UIManager.getDefaults().put("TabbedPaneUI", "com.package.MyTabbedPaneUI");
Then you need to define a TabChangeListener class to add as a client property of the specific tabbed pane, that has the tabWillChange method, which should throw a PropertyVetoException if the change should not be allowed. Otherwise, do nothing.
Message was edited by:
bsampieri
Hmmm,
And there I was hoping for a
myTabbedPane.dontBloodyChangeTilliTellYouTo();
Anyway, as it will probably take me the rest of my natural life to intergrate the code you have written into my app, and longer (if that is possible) to understand it, I will give the the dukes, while they are still legal tender and report back if I ever get it to work?!
Thanks (I think) for the help,
Kris
Hi, sorry for the delayed reply, but I didn't think I'd get any more replies. I have put a ChangeListener in place and it does what you suggest ?it works but it is messy, and doesn抰 really resolve my problem as the new Pane has already loaded when the ChangeLisetener implements.
Your other idea also sounds promising (well from a novices point of view anyway) can you point me in the right direction so I can attempt setting the model to a custom subclass of SingleSelectionModel as you suggest.
Thanks in advance,
Kris