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 boolean requestFocus = true;
 
 
     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 (requestFocus) {
 
                    Runnable transferFocus = new Runnable() {
 
 
                        public void run() {
 
                            pane.getSelectedComponent().transferFocus();
 
                        }
 
                    };
 
                    SwingUtilities.invokeLater(transferFocus);
 
                }
 
 
                 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();
    }
 
 
    public void setRequestFocus(boolean b) {
 
        requestFocus = b;
 
    }
 
 
    public boolean isRequestFocus() {
 
        return requestFocus;
 
 
     }
 
     }
  
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>