Illustrates the use of several dynamically created Swing controls, including AgcJTable, JToolbar, JSplitPane, JEditorPane, and JScrollPane.
You can run this technique code from:
NOTE First make sure that database is running on your localhost SilverStream Server | |
See the techniques Using the JTable Control and Implementing a Nested Layout in the Application Techniques |
In frmSwingSampler, a pane with a splitter bar contains a table and an editor pane. A toolbar lets the user change the settings of the split pane. These controls are arranged and added to the form in the addControls()
method, which overrides AgfForm's addControls()
.
The JSplitPane control contains two panes that display a data-loaded AgcJTable and a JEditorPane. The JSplitPane has a divider, which the user can drag to control the sizes of the panes. A one-touch expander icon on the divider moves the divider to one edge or the other without dragging. Both the AgcJTable and the JEditorPane have a JScrollPane to handle scrolling.
The JToolbar control has toggle buttons that affect the split pane and its controls. The user can open a file in the editor pane, specify whether the controls are continuously adjusted as the user drags the divider, disable or enable the one-touch expander, and tile the panes horizontally or vertically.
The diagram illustrates how the Swing components are nested. Scroll panes are placed in each part of the split pane, and the AgcJTable and JEditorPane are in the scroll panes. A JPanel is the container for all the components. It uses BorderLayout with the toolbar in the north section and the split pane in the center.
This code in addControls()
creates the JPanel and a scroll pane for the editor pane.
JPanel wrapper = new JPanel (); wrapper.setLayout(new BorderLayout()); // add the ScrollPane to the JEditorPane m_jscrollPaneRight = new JScrollPane (m_jeditorPane); // Create the SplitPane, with its two controls m_jSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, jtableCompaniesScrollPane, m_jscrollPaneRight); // Add the m_jSplitPane to the wrapper panel in the Center wrapper.add(m_jSplitPane, BorderLayout.CENTER);
jtableCompanies
and jtableCompaniesScrollPane
instance variables in the declarations section.
You build up a toolbar by adding separators and buttons in the order you want them to appear. The toggle buttons have already been defined in the Designer.
This code in the addControls()
method creates the toolbar and adds the first separator.
// Create a toolbar JToolBar jtoolBar = new JToolBar (); // Add a beginning separator jtoolBar.addSeparator(m_bigSeparator);
m_bigSeparator
is a Dimension object 9 pixels wide. It is initialized in the Declarations section.
final static Dimension m_bigSeparator = new Dimension(9, 9);
This code gets a button image from the image store in the current database.
// Set up variables to help find the images for the buttons String sDatabaseURL = agGeneral.getDatabaseURL().toString(); String sURL = ""; URL urlImage = null; try { sURL = sDatabaseURL + "SilverStream/Objectstore/Images/tbOpen.gif"; urlImage = new URL(sURL); } catch (Exception e) { agDialog.displayError(e); }
database/SilverStream/Objectstore/Images/filename.ext
This code initializes the button with a text label and an image and adds it to the toolbar. (Getting the image from the database is described above.) All of the buttons are set up with similar code.
jbtnOpen.setToolTipText("Open"); ImageIcon imgIcon = new ImageIcon(urlImage, "Open"); jbtnOpen.setIcon((javax.swing.Icon) imgIcon); jbtnOpen.setMargin(new Insets(0,0,0,0)); jbtnOpen.getAccessibleContext().setAccessibleName("Open"); jtoolBar.add(jbtnOpen); jbtnOpen.addActionListener (this);
This code adds the toolbar to the wrapper JPanel in its north region. (The split pane has already been added in the center region.)
// add the toolbar to the North wrapper.add(jtoolBar, BorderLayout.NORTH);
This code adds the wrapper JPanel to the form and calls setBounds()
to specify its size and position.
add (wrapper); wrapper.setBounds (m_xWrapper, m_yWrapper, m_widthWrapper, m_heightWrapper);
Other controls created in the Designer need to be added in addControls()
.
add (dataCompanies); add(lblTitle);
frmSwingSampler calls the retrieveTheData()
method in the formActivate event. It loads the AgcJTable with data retrieved by the AgcData control.
public void retrieveTheData() { try { // Populate the table rows int[] columnIndexes = {dataCompanies.getPropertyIndex("companyname"), dataCompanies.getPropertyIndex("description") }; int valueColumnIndex = dataCompanies.getPropertyIndex("companyid"); dataCompanies.query(""); // Load the table using the row cursor jtableCompanies.loadFromRowCursor(dataCompanies, columnIndexes, null, valueColumnIndex, m_sColumnTitles); } catch(Exception ex) { agDialog.displayError(ex); } }
query()
method for the AgcData control dataCompanies
retrieves the data.
loadFromRowCursor()
gets the retrieved data from the properties (columns) of dataCompanies
.
editableColumns
argument).
jtableCompanies
is not data-bound so the value column is specified but not used anywhere.
m_sColumnTitles
array were specified in the Declarations section.
The first toolbar button has code that opens a file in the editor pane. This code in its actionPerformed event displays a standard file dialog to let the user choose a file.
FileDialog fileDialog = new FileDialog (getFrame (), "Select a File", FileDialog.LOAD); fileDialog.show (); String sFilename = fileDialog.getFile (); String sDirectory = fileDialog.getDirectory (); //test if cancel was hit if (sFilename == null || sDirectory ==null) return; File fileSelected = new File (sDirectory + sFilename);
The event code continues with special handling for HTML, RTF, and DOC files. For other types, it just assigns the file contents to the editor.
if (sFilename.endsWith (".htm") || sFilename.endsWith (".html")) { m_jeditorPane.setPage ("file:" + sDirectory + sFilename); } // RTF doesn't work yet else if (sFilename.endsWith (".rtf") || sFilename.endsWith (".doc")) { String sContents = getFileContents (fileSelected); m_jeditorPane.setContentType ("text/rtf"); m_jeditorPane.setText (sContents); } else { String sContents = getFileContents (fileSelected); m_jeditorPane.setText (sContents); }
setPage()
method for JEditorPane knows how to handle an HTML file. The code doesn't need to call getFileContents()
for that file type.
getFileContents()
reads the file. It is described next.
The user-defined method getFileContents()
reads the file.
public String getFileContents(File filename) { String sContents = new String(); char[] chBuffer = new char[50000]; InputStreamReader reader; try { reader = new FileReader(filename); int iNumCharsRead; while ((iNumCharsRead = reader.read(chBuffer, 0, chBuffer.length)) != -1) { sContents = sContents + new String(chBuffer, 0, iNumCharsRead); } } catch (java.io.IOException ex) { sContents = "Could not load file: " + filename; } return sContents; }
chBuffer
. The actual number of characters read is assigned to iNumCharsRead.
chBuffer
to a String before appending it to sContents
, the code converts only the number of characters that were read. On the next-to-last iteration, the buffer probably won't be full.
read()
returns -1, the reader is at the end of the file.