JCardPane: Unterschied zwischen den Versionen
Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen (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…“) |
|||
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>