![JAR search and dependency download from the Maven repository](/logo.png)
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