All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.cuf.ui.table.BasicDialog Maven / Gradle / Ivy

The newest version!
package net.sf.cuf.ui.table;

import net.sf.cuf.ui.SwingDecorator;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.KeyEvent;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JComponent;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;


/**
 * Base class for our modal dialogs.
 * This base class offers the following benefits:
 * 
    *
  • dialog is made modal
  • *
  • handling of close button in window border
  • *
  • layout of OK and Cancel buttons
  • *
  • OK and Cancel buttons acting as default buttons
  • *
  • positioning of dialog relative to owner
  • *
  • method {@link #show} is disabled
  • *
  • dialog is not resizable but will be repacked on each show
  • *
  • convenience method to extract header names from a table model
  • *
* * @author Hendrik Wördehoff, sd&m AG */ public abstract class BasicDialog extends JDialog { /** Identifier of the dialog for I18N purposes. */ protected String mKennung; /** OK button. */ protected JButton mButtonOK; /** Cancel button. */ protected JButton mButtonCancel; /** Flag if the dialog has been initially positioned. */ private boolean mPositioned = false; /** * Constructor. * @param pOwner parent window (must not be null) * @param pKennung identifier for I18N purposes (must not be null or empty) */ public BasicDialog(final Frame pOwner, final String pKennung) { super(pOwner, true); // check preconditions if ( pOwner == null ) throw new IllegalArgumentException("owner must not be null"); if ( pKennung == null || pKennung.length() == 0 ) throw new IllegalArgumentException("kennung must not be null or empty"); mKennung = pKennung; // initialize dialog SwingDecorator.initialize(this, pKennung); setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); setResizable(false); addWindowListener(new WindowAdapter() { public void windowClosing(final WindowEvent pEvent) { processDialogCancel(); } }); } /** * Create the OK and Cancel buttons, lay them out and set them up as default buttons. * Activating the buttons will call {@link #processDialogOk} and {@link #processDialogCancel} respectively. * @return {@link Container} holding the buttons */ protected Container createOkCancelButtons() { // create a container Box box = Box.createHorizontalBox(); // create the buttons mButtonOK = new JButton(); SwingDecorator.initialize(mButtonOK, mKennung +"_OK"); mButtonOK.addActionListener(pEvent -> processDialogOk()); box.add(mButtonOK); box.add(Box.createHorizontalStrut(10)); mButtonCancel = new JButton(); SwingDecorator.initialize(mButtonCancel, mKennung +"_CANCEL"); mButtonCancel.addActionListener(pEvent -> processDialogCancel()); box.add(mButtonCancel); // align width of OK and Cancel buttons Dimension d1 = mButtonOK.getPreferredSize(); Dimension d2 = mButtonCancel.getPreferredSize(); int width = Math.max(d1.width, d2.width); d1.width = width; d2.width = width; mButtonOK.setPreferredSize(d1); mButtonOK.setMinimumSize (d1); mButtonOK.setMaximumSize (d1); mButtonCancel.setPreferredSize(d2); mButtonCancel.setMinimumSize (d2); mButtonCancel.setMaximumSize (d2); // set default button mButtonOK.setDefaultCapable(true); mButtonCancel.setDefaultCapable(true); getRootPane().setDefaultButton(mButtonOK); // resolve conflicts between the two buttons mButtonCancel.addFocusListener(new FocusAdapter() { // with Windows L&F the default button moves on focus changes so we have to move it back again public void focusLost(final FocusEvent pEvent) { getRootPane().setDefaultButton(mButtonOK); } // automatic moving of the default button does not work with Metal L&F so we have to do it ourselves public void focusGained(final FocusEvent pEvent) { getRootPane().setDefaultButton(mButtonCancel); } }); // return button container return box; } /** * Show the dialog after adjusting the layout and positioning it properly. * This method will block until the dialog is closed. */ protected void showDialog() { // adjust layout pack(); // center dialog over window on first opening if (!mPositioned) { setLocationRelativeTo(getOwner()); mPositioned = true; } // show dialog, will block until hide() gets called super.setVisible(true); } /** * Process a positive user action. */ protected abstract void processDialogOk(); /** * Process a negative user action. */ protected abstract void processDialogCancel(); /** * Convenience method to extract the header names from the given table model. * The first offset entries in this list will be the empty * string. The other entries will be the column names in the order * delivered by the table model. * @param pModel table model * @param pOffset number of empty strings at the beginning of the array * @return array of header names */ protected Object[] fetchColumnHeaders(final TableModel pModel, int pOffset) { pOffset = Math.max(pOffset, 0); // keep the offset greater or equal to 0 int columns = pModel.getColumnCount(); Object[] header = new Object[columns+ pOffset]; for ( int i = 0; i < header.length; i++ ) { header[i] = (i < pOffset) ? "" : pModel.getColumnName(i- pOffset); } return header; } /** * Convenience method to extract the header names from the given column model. * The first offset entries in this list will be the empty * string. The other entries will be the column names in the order * delivered by the column model. * @param pColumnModel column model * @param pOffset number of empty strings at the beginning of the array * @return array of header names */ protected Object[] fetchVisibleColumnHeaders(final TableColumnModel pColumnModel, int pOffset) { pOffset = Math.max(pOffset, 0); // keep the offset greater or equal to 0 int columns = pColumnModel.getColumnCount(); Object[] header = new Object[columns+ pOffset]; for ( int i = 0; i < header.length; i++ ) { header[i] = (i < pOffset) ? "" : pColumnModel.getColumn(i- pOffset).getHeaderValue(); } return header; } /** * Called by the constructor methods to create the default rootPane. * We add a escape listener that reacts on ESC and calls processDialogCancel(). */ protected JRootPane createRootPane() { KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); JRootPane newRootPane = super.createRootPane(); ActionListener escapeListener= pEvent -> processDialogCancel(); newRootPane.registerKeyboardAction(escapeListener, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); return newRootPane; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy