JCardPane: Unterschied zwischen den Versionen
Aus Byte-Welt Wiki
Die Seite wurde neu angelegt: „<code=java>→* JCardPane.java * wraps a JTabbedPane, optionally hiding the tabs. * The main method shows an example: import java.awt.*; import java.awt.ev…“ |
Keine Bearbeitungszusammenfassung |
||
| Zeile 2: | Zeile 2: | ||
* JCardPane.java | * JCardPane.java | ||
* wraps a JTabbedPane, optionally hiding the tabs. | * wraps a JTabbedPane, optionally hiding the tabs. | ||
* The main method shows an example | * The main method shows an example. | ||
*/ | */ | ||
import java.awt.*; | import java.awt.*; | ||
import java.awt.event.*; | import java.awt.event.*; | ||
import java.beans.*; | |||
import java.util.*; | |||
import javax.swing.*; | import javax.swing.*; | ||
import javax.swing.event.*; | import javax.swing.event.*; | ||
| Zeile 15: | Zeile 17: | ||
private JTabbedPane pane; | private JTabbedPane pane; | ||
private CardAction nextAction; | private CardAction nextAction; | ||
private CardAction previousAction; | private CardAction previousAction; | ||
| Zeile 53: | Zeile 54: | ||
public JCardPane(boolean tabbed) { | public JCardPane(boolean tabbed) { | ||
pane = new JTabbedPane(); | pane = new JTabbedPane(); | ||
new TabFocusHandler(pane); | |||
uiTabbed = pane.getUI(); | uiTabbed = pane.getUI(); | ||
if (!tabbed) { | if (!tabbed) { | ||
| Zeile 60: | Zeile 62: | ||
public void stateChanged(ChangeEvent e) { | public void stateChanged(ChangeEvent e) { | ||
if (nextAction != null) { | if (nextAction != null) { | ||
nextAction.setEnabled(hasNext()); | nextAction.setEnabled(hasNext()); | ||
| Zeile 143: | Zeile 136: | ||
public Component getCurrent() { | public Component getCurrent() { | ||
return pane.getSelectedComponent(); | return pane.getSelectedComponent(); | ||
} | } | ||
| Zeile 204: | Zeile 189: | ||
} else { | } else { | ||
previous(); | previous(); | ||
} | |||
} | |||
} | |||
/* | |||
* Manage the focus when a new tab is selected. You can select a focus policy: | |||
* a) Reset Focus - focus is reset to the first focusable component on the tab | |||
* b) Retain Focus - focus returns to the last component with focus on the tab | |||
* | |||
* In addition you add tabs that you want to exclude from the focus policy, | |||
* in which case the other policy will be in effect. | |||
*/ | |||
class TabFocusHandler implements ChangeListener, PropertyChangeListener { | |||
public final static int RESET_FOCUS = 0; | |||
public final static int RETAIN_FOCUS = 1; | |||
private HashMap<Component, Component> tabFocus = new HashMap<Component, Component>(); | |||
private HashSet<Component> exceptions; | |||
private JTabbedPane tabbedPane; | |||
private int focusPolicy; | |||
/* | |||
* Create with the default Retain Focus policy | |||
*/ | |||
public TabFocusHandler(JTabbedPane tabbedPane) { | |||
this(tabbedPane, RETAIN_FOCUS); | |||
} | |||
/* | |||
* Create using the specified focus policy | |||
*/ | |||
public TabFocusHandler(JTabbedPane tabbedPane, int focusPolicy) { | |||
if (focusPolicy != RESET_FOCUS && focusPolicy != RETAIN_FOCUS) { | |||
throw new IllegalArgumentException("Invalid focus policy"); | |||
} | |||
this.tabbedPane = tabbedPane; | |||
this.focusPolicy = focusPolicy; | |||
// Add listeners to manage a tab change | |||
tabbedPane.addChangeListener(this); | |||
KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); | |||
focusManager.addPropertyChangeListener("permanentFocusOwner", this); | |||
} | |||
/* | |||
* Specify a tab with an exception to the focus policy rule | |||
*/ | |||
public void addException(int index) { | |||
if (exceptions == null) { | |||
exceptions = new HashSet<Component>(); | |||
} | |||
Component key = tabbedPane.getComponentAt(index); | |||
exceptions.add(key); | |||
} | |||
/* | |||
* Tab has changed. Focus on saved component for the given tab. | |||
* When there is no saved component, focus on the first component. | |||
*/ | |||
public void stateChanged(ChangeEvent e) { | |||
Component key = tabbedPane.getComponentAt(tabbedPane.getSelectedIndex()); | |||
if (key == null) { | |||
return; | |||
} | |||
Component value = tabFocus.get(key); | |||
// First time selecting this tab or focus policy is RESET_FOCUS | |||
if (value == null) { | |||
key.transferFocus(); | |||
tabFocus.put(key, value); | |||
} else // Use the saved component for focusing | |||
{ | |||
value.requestFocusInWindow(); | |||
} | |||
} | |||
/* | |||
* Track focus changes and update the current focus component | |||
* for the current tab | |||
*/ | |||
public void propertyChange(PropertyChangeEvent e) { | |||
// No need to track focus change | |||
if (exceptions == null && focusPolicy == RESET_FOCUS) { | |||
return; | |||
} | |||
// Check for exceptions to the focus policy exist | |||
Component key = tabbedPane.getComponentAt(tabbedPane.getSelectedIndex()); | |||
if (exceptions != null) { | |||
if (focusPolicy == RESET_FOCUS && !exceptions.contains(key)) { | |||
return; | |||
} | |||
if (focusPolicy == RETAIN_FOCUS && exceptions.contains(key)) { | |||
return; | |||
} | |||
} | |||
// Track focus changes for the tab | |||
Component value = (Component) e.getNewValue(); | |||
if (value != null && SwingUtilities.isDescendingFrom(value, key)) { | |||
tabFocus.put(key, value); | |||
} | } | ||
} | } | ||
| Zeile 229: | Zeile 311: | ||
public Card(final String name) { | public Card(final String name) { | ||
JTextField tf = new JTextField(20); | JTextField tf = new JTextField(20); | ||
tf.setText(name); | |||
add(tf); | |||
tf = new JTextField(20); | |||
tf.setText(name); | tf.setText(name); | ||
add(tf); | add(tf); | ||
Version vom 15. Oktober 2009, 22:32 Uhr
<code=java>/*
* JCardPane.java * wraps a JTabbedPane, optionally hiding the tabs. * The main method shows an example. */
import java.awt.*; import java.awt.event.*; import java.beans.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.plaf.TabbedPaneUI; import javax.swing.plaf.basic.BasicTabbedPaneUI;
public class JCardPane extends JComponent {
private JTabbedPane pane;
private CardAction nextAction;
private CardAction previousAction;
private TabbedPaneUI uiTabbed;
private TabbedPaneUI uiNoTabs = new BasicTabbedPaneUI() {
@Override
protected int calculateTabAreaHeight(int tabPlacement,
int horizRunCount, int maxTabHeight) {
return 0;
}
@Override
protected Insets getContentBorderInsets(int tabPlacement) {
return new Insets(0, 0, 0, 0);
}
@Override
protected MouseListener createMouseListener() {
return null;
}
@Override
protected void installKeyboardActions() {
}
@Override
protected int calculateTabWidth(int tabPlacement, int tabIndex, FontMetrics metrics) {
return 0;
}
};
public JCardPane() {
this(false);
}
public JCardPane(boolean tabbed) {
pane = new JTabbedPane();
new TabFocusHandler(pane);
uiTabbed = pane.getUI();
if (!tabbed) {
hideTabs();
}
pane.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if (nextAction != null) {
nextAction.setEnabled(hasNext());
}
if (previousAction != null) {
previousAction.setEnabled(hasPrevious());
}
}
});
setLayout(new BorderLayout());
add(pane);
}
public int first() {
return show(0);
}
public int last() {
return show(-1);
}
public int next() {
return show(pane.getSelectedIndex() + 1);
}
public int previous() {
return show(pane.getSelectedIndex() - 1);
}
public int show(final int index) {
if (pane.getTabCount() == 0) {
return -1;
}
if (index >= pane.getTabCount()) {
pane.setSelectedIndex(0);
return 0;
}
if (index < 0) {
pane.setSelectedIndex(pane.getTabCount() - 1);
return pane.getTabCount() - 1;
}
pane.setSelectedIndex(index);
return index;
}
public int show(final String name) {
int index = pane.indexOfTab(name);
if (index >= 0) {
pane.setSelectedIndex(index);
}
return index;
}
public int show(final JComponent card) {
int index = pane.indexOfComponent(card);
if (index < 0) {
index = pane.getTabCount();
pane.addTab(card.getName(), card);
}
pane.setSelectedIndex(index);
return index;
}
public boolean hasNext() {
return pane.getSelectedIndex() < pane.getComponentCount() - 1;
}
public boolean hasPrevious() {
return pane.getSelectedIndex() > 0;
}
public Component getCurrent() {
return pane.getSelectedComponent();
}
public void addChangeListener(ChangeListener l) {
pane.addChangeListener(l);
}
public void removeChangeListener(ChangeListener l) {
pane.removeChangeListener(l);
}
public void hideTabs() {
pane.setUI(uiNoTabs);
}
public void showTabs() {
pane.setUI(uiTabbed);
}
public Action getNextAction() {
if (nextAction == null) {
nextAction = new CardAction("Next", true);
nextAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_N);
nextAction.setEnabled(hasNext());
}
return nextAction; }
public Action getPreviousAction() {
if (previousAction == null) {
previousAction = new CardAction("Previous", false);
previousAction.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_P);
previousAction.setEnabled(hasPrevious());
}
return previousAction; }
class CardAction extends AbstractAction {
private boolean isNext;
public CardAction(String text, boolean isNext) {
super(text);
this.isNext = isNext;
putValue(Action.SHORT_DESCRIPTION, getValue(Action.NAME));
}
public void actionPerformed(ActionEvent e) {
if (isNext) {
next();
} else {
previous();
}
}
}
/*
* Manage the focus when a new tab is selected. You can select a focus policy:
* a) Reset Focus - focus is reset to the first focusable component on the tab
* b) Retain Focus - focus returns to the last component with focus on the tab
*
* In addition you add tabs that you want to exclude from the focus policy,
* in which case the other policy will be in effect.
*/
class TabFocusHandler implements ChangeListener, PropertyChangeListener {
public final static int RESET_FOCUS = 0;
public final static int RETAIN_FOCUS = 1;
private HashMap<Component, Component> tabFocus = new HashMap<Component, Component>();
private HashSet<Component> exceptions;
private JTabbedPane tabbedPane;
private int focusPolicy;
/*
* Create with the default Retain Focus policy
*/
public TabFocusHandler(JTabbedPane tabbedPane) {
this(tabbedPane, RETAIN_FOCUS);
}
/*
* Create using the specified focus policy
*/
public TabFocusHandler(JTabbedPane tabbedPane, int focusPolicy) {
if (focusPolicy != RESET_FOCUS && focusPolicy != RETAIN_FOCUS) {
throw new IllegalArgumentException("Invalid focus policy");
}
this.tabbedPane = tabbedPane;
this.focusPolicy = focusPolicy;
// Add listeners to manage a tab change
tabbedPane.addChangeListener(this);
KeyboardFocusManager focusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
focusManager.addPropertyChangeListener("permanentFocusOwner", this);
}
/*
* Specify a tab with an exception to the focus policy rule
*/
public void addException(int index) {
if (exceptions == null) {
exceptions = new HashSet<Component>();
}
Component key = tabbedPane.getComponentAt(index);
exceptions.add(key);
}
/*
* Tab has changed. Focus on saved component for the given tab.
* When there is no saved component, focus on the first component.
*/
public void stateChanged(ChangeEvent e) {
Component key = tabbedPane.getComponentAt(tabbedPane.getSelectedIndex());
if (key == null) {
return;
}
Component value = tabFocus.get(key);
// First time selecting this tab or focus policy is RESET_FOCUS
if (value == null) {
key.transferFocus();
tabFocus.put(key, value);
} else // Use the saved component for focusing
{
value.requestFocusInWindow();
}
}
/*
* Track focus changes and update the current focus component
* for the current tab
*/
public void propertyChange(PropertyChangeEvent e) {
// No need to track focus change
if (exceptions == null && focusPolicy == RESET_FOCUS) {
return;
}
// Check for exceptions to the focus policy exist
Component key = tabbedPane.getComponentAt(tabbedPane.getSelectedIndex());
if (exceptions != null) {
if (focusPolicy == RESET_FOCUS && !exceptions.contains(key)) {
return;
}
if (focusPolicy == RETAIN_FOCUS && exceptions.contains(key)) {
return;
}
}
// Track focus changes for the tab
Component value = (Component) e.getNewValue();
if (value != null && SwingUtilities.isDescendingFrom(value, key)) {
tabFocus.put(key, value);
}
}
}
//for testing only:
public static void main(final String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
Runnable gui = new Runnable() {
@Override
public void run() {
final JFrame f = new JFrame("JCardPane Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400, 150);
f.setLocationRelativeTo(null);
final JCardPane cardPane = new JCardPane();
f.add(cardPane, BorderLayout.CENTER);
class Card extends JPanel {
public Card(final String name) {
JTextField tf = new JTextField(20);
tf.setText(name);
add(tf);
tf = new JTextField(20);
tf.setText(name);
add(tf);
setName(name);
}
}
for (int i = 0; i < 5; i++) {
cardPane.show(new Card(String.valueOf(i + 1)));
}
cardPane.first();
JPanel control = new JPanel();
control.add(new JButton(cardPane.getPreviousAction()));
control.add(new JButton(cardPane.getNextAction()));
final JToggleButton btTabbed = new JToggleButton("Tabbed");
btTabbed.setFocusable(false);
control.add(btTabbed);
btTabbed.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (btTabbed.isSelected()) {
cardPane.showTabs();
} else {
cardPane.hideTabs();
}
}
});
f.add(control, BorderLayout.SOUTH);
f.setVisible(true);
}
};
//GUI must start on EventDispatchThread:
SwingUtilities.invokeLater(gui);
}
} </code=java>
