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

org.jdesktop.swingx.demos.table.XTableDemo Maven / Gradle / Ivy

/* Copyright 2007-2009 Sun Microsystems, Inc.  All Rights Reserved.
Copyright notice, list of conditions and disclaimer see LICENSE file
*/ 
package org.jdesktop.swingx.demos.table;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.swing.Box;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.SwingWorker.StateValue;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.table.JTableHeader;

import org.jdesktop.swingx.JXFrame;
import org.jdesktop.swingx.JXFrame.StartPosition;
import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.JXStatusBar;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.JXTableHeader;
import org.jdesktop.swingx.decorator.HighlighterFactory;
import org.jdesktop.swingx.table.TableColumnExt;

import swingset.AbstractDemo;

/**
 * A demo for the {@code JXTable}. This demo displays the same functionality as
 * {@link swingset.TableDemo TableDemo}, using SwingX components and methodologies.
 * 

* It is not possible to extend {@code TableDemo}, since the display components are private. * This class replicates contents and behavior in that class and may fall out of sync. * * @author Karl George Schaefer * @author Jeanette Winzenberg (Devoxx '08 version) * @author aim (original TableDemo) * @author EUG https://github.com/homebeaver (reorg+simplify) */ //@DemoProperties( // value = "JXTable Demo", // category = "Data", // description = "Demonstrates JXTable, an enhanced data grid display.", // sourceFiles = { // "org/jdesktop/swingx/demos/table/XTableDemo.java", // "org/jdesktop/swingx/demos/table/OscarRendering.java", // "org/jdesktop/swingx/demos/table/CustomColumnFactory.java", // "org/jdesktop/swingx/demos/table/OscarFiltering.java", // "org/jdesktop/swingx/demos/table/resources/XTableDemo.properties" // } // ) public class XTableDemo extends AbstractDemo { private static final long serialVersionUID = -2616149327587528185L; static final Logger LOG = Logger.getLogger(XTableDemo.class.getName()); private static final String DESCRIPTION = "Demonstrates JXTable, an enhanced data grid display."; /** * main method allows us to run as a standalone demo. * @param args params */ public static void main(String[] args) { SwingUtilities.invokeLater( () -> { // no controller JXFrame frame = new JXFrame(DESCRIPTION, exitOnClose); AbstractDemo demo = new XTableDemo(frame); frame.setStartPosition(StartPosition.CenterInScreen); //frame.setLocationRelativeTo(controller); frame.getContentPane().add(demo); frame.pack(); frame.setVisible(true); }); } private OscarTableModel oscarModel; // Controller/NORTH: private JXPanel controlPanel; private JTextField filterField; private JCheckBox winnersCheckbox; private OscarFiltering filterController; private Stacker dataPanel; // com.sun.swingset3.demos.Stacker extends JLayeredPane mit timing.Animator private JXTable oscarTable; // SOUTH: private JComponent statusBarLeft; private JLabel actionStatus; private JLabel tableStatus; private JLabel tableRows; private JProgressBar progressBar; /** * XTableDemo Constructor * * @param frame controller Frame */ public XTableDemo(Frame frame) { super(new BorderLayout()); frame.setTitle(getBundleString("frame.title", DESCRIPTION)); super.setPreferredSize(PREFERRED_SIZE); super.setBorder(new BevelBorder(BevelBorder.LOWERED)); // initComponents: add(getControlPanel(), BorderLayout.NORTH); oscarTable = createXTable(); oscarTable.setName("oscarTable"); JScrollPane scrollpane = new JScrollPane(oscarTable); dataPanel = new Stacker(scrollpane); add(dataPanel, BorderLayout.CENTER); add(createStatusBar(), BorderLayout.SOUTH); // Alternativ JXStatusBar im frame configureDisplayProperties(); // Filter control create the controller filterController = new OscarFiltering(oscarTable); // JXTable data properties oscarModel = new OscarTableModel(); // set the table model after setting the factory oscarTable.setModel(oscarModel); // oscarModel.addTableModelListener( tableModelEvent -> { updateStatusBar(); }); // JXTable column properties // some display properties can be configured only after the model has been set, // here: configure the view sequence of columns to be different from the model oscarTable.setColumnSequence(new Object[] { "yearColumn" , "categoryColumn" , "movieTitleColumn" , "nomineesColumn" }); // start(); } @Override public JXPanel getControlPane() { return emptyControlPane(); } private JXPanel getControlPanel() { GridBagLayout gridbag = new GridBagLayout(); controlPanel = new JXPanel(gridbag); GridBagConstraints c = new GridBagConstraints(); c.gridx = 0; c.gridy = 1; c.gridheight = 1; c.insets = new Insets(20, 10, 0, 10); c.anchor = GridBagConstraints.SOUTHWEST; JLabel searchLabel = new JLabel(); searchLabel.setName("searchLabel"); searchLabel.setText(getBundleString("searchLabel.text")); controlPanel.add(searchLabel, c); c.gridx = 0; c.gridy = 2; c.weightx = 1.0; c.insets.top = 0; c.insets.bottom = 12; c.anchor = GridBagConstraints.SOUTHWEST; //c.fill = GridBagConstraints.HORIZONTAL; filterField = new JTextField(24); filterField.addActionListener( event -> { filterController.setFilterString(event.getActionCommand()); updateStatusBar(); }); controlPanel.add(filterField, c); c.gridx = 1; c.gridy = 2; c.gridwidth = GridBagConstraints.REMAINDER; //c.insets.right = 24; //c.insets.left = 12; c.weightx = 0.0; c.anchor = GridBagConstraints.EAST; c.fill = GridBagConstraints.NONE; winnersCheckbox = new JCheckBox(); winnersCheckbox.setName("winnersLabel"); winnersCheckbox.setText(getBundleString("winnersLabel.text")); winnersCheckbox.addActionListener( event -> { boolean showOnlyWinners = ((JCheckBox)event.getSource()).isSelected(); filterController.setShowOnlyWinners(showOnlyWinners); updateStatusBar(); }); controlPanel.add(winnersCheckbox, c); return controlPanel; } /** * Customizes display properties of contained components. * This is data-unrelated. */ private void configureDisplayProperties() { // JXTable display properties // show column control oscarTable.setColumnControlVisible(true); // replace grid lines with striping oscarTable.setShowGrid(false, false); oscarTable.addHighlighter(HighlighterFactory.createSimpleStriping()); // initialize preferred size for table's viewable area oscarTable.setVisibleRowCount(10); // // JXTable column properties // create and configure a custom column factory CustomColumnFactory factory = new CustomColumnFactory() { // titles from props protected void configureTitle(TableColumnExt columnExt) { columnExt.setTitle(getBundleString(OscarTableModel.columnIds[columnExt.getModelIndex()])); } }; OscarRendering.configureColumnFactory(factory, getClass()); // set the factory before setting the table model oscarTable.setColumnFactory(factory); // // DemoUtils.setSnippet("JXTable display properties", oscarTable); // DemoUtils.setSnippet("JXTable column properties", oscarTable.getTableHeader()); // DemoUtils.setSnippet("Filter control", filterField, winnersCheckbox, tableStatus, tableRows); // DemoUtils.setSnippet("Use SwingWorker to asynchronously load the data", statusBarLeft, // (JComponent) statusBarLeft.getParent()); } /** * Updates status labels. * Called during loading and on changes to the filter controller state. */ protected void updateStatusBar() { if(filterController.isFilteringByString()) { tableStatus.setName("searchCountLabel"); tableStatus.setText(getBundleString("searchCountLabel.text")); } else { tableStatus.setName("rowCountLabel"); tableStatus.setText(getBundleString("rowCountLabel.text")); } tableRows.setText("" + oscarTable.getRowCount()); } /** * Callback method for demo loader. */ public void start() { if (oscarModel.getRowCount() != 0) return; //Use SwingWorker to asynchronously load the data // create SwingWorker which will load the data on a separate thread SwingWorker loader = new OscarDataLoader(XTableDemo.class.getResource("resources/oscars.xml"), oscarModel); // ohne bind: loader.addPropertyChangeListener( propertyChangeEvent -> { if ("state".equals(propertyChangeEvent.getPropertyName())) { StateValue state = (StateValue)propertyChangeEvent.getNewValue(); LOG.info("loader StateValue:" + state); // damit ampel steuern updateStatusBar(); if (state == StateValue.DONE) { statusBarLeft.remove(progressBar); statusBarLeft.remove(actionStatus); revalidate(); repaint(); } } if ("progress".equals(propertyChangeEvent.getPropertyName())) { int progress = (Integer)propertyChangeEvent.getNewValue(); //LOG.info("loader progress:" + progress); progressBar.setValue(progress); updateStatusBar(); } }); // alternativly / needs artifact/org.jdesktop/beansbinding // bind the worker's progress notification to the progressBar // and the worker's state notification to this // BindingGroup group = new BindingGroup(); // group.addBinding(Bindings.createAutoBinding(AutoBinding.UpdateStrategy.READ // , loader, BeanProperty.create("progress") // , progressBar, BeanProperty.create("value") // )); // group.addBinding(Bindings.createAutoBinding(AutoBinding.UpdateStrategy.READ // , loader, BeanProperty.create("state") // , this, BeanProperty.create("loadState") // )); // group.bind(); StateValue state = loader.getState(); // PENDING - STARTED - DONE LOG.info("loader StateValue:" + state); loader.execute(); // } //Use SwingWorker to asynchronously load the data specialized on OscarCandidate /* * @param the result type returned by this {@code SwingWorker's} * {@code doInBackground} and {@code get} methods * @param the type used for carrying out intermediate results by this * {@code SwingWorker's} {@code publish} and {@code process} methods */ private class OscarDataLoader extends SwingWorker, OscarCandidate> { private final URL oscarData; private final OscarTableModel oscarModel; private final List candidates = new ArrayList(); // private JLabel credits; private final int expectedNumber = 8540; // ctor: private OscarDataLoader(URL oscarURL, OscarTableModel oscarTableModel) { this.oscarData = oscarURL; this.oscarModel = oscarTableModel; } /* nach dem Laden: swingset3 8522/8545 (BUG dort) , hier: 8540 * showOnlyWinners: beide 1758 */ //Use SwingWorker to asynchronously load the data // background task let a parser do its stuff and update a progress bar @Override public List doInBackground() { OscarDataParser parser = new OscarDataParser() { @Override // implement abstract addCandidate protected void addCandidate(OscarCandidate candidate) { candidates.add(candidate); if (candidates.size() % 3 == 0) { try { // slow it down so we can see progress :-) Thread.sleep(1); } catch (Exception ex) { } } publish(candidate); setProgress(100 * candidates.size() / expectedNumber); } }; parser.parseDocument(oscarData); if(super.isCancelled()) { LOG.warning("cancelled "+candidates.size()+"/"+expectedNumber + " "+100 * candidates.size() / expectedNumber + "%"); super.firePropertyChange("cancelled", false, true); } else { LOG.info("DONE "+candidates.size()+"/"+expectedNumber + " "+100 * candidates.size() / expectedNumber + "%"); } return candidates; } // /** * Receives data chunks asynchronously on the EDT * * @param chunks intermediate results to process */ @Override protected void process(List moreCandidates) { //LOG.info("chunks#:"+moreCandidates.size()); if (credits == null) { showCredits(); } oscarModel.add(moreCandidates); } // For older Java 6 on OS X @SuppressWarnings("unused") protected void process(OscarCandidate... moreCandidates) { for (OscarCandidate candidate : moreCandidates) { oscarModel.add(candidate); } } //Use SwingWorker to asynchronously load the data // show a transparent overlay on start loading private void showCredits() { credits = new JLabel(); credits.setName("credits"); credits.setText(getBundleString("credits.text")); credits.setFont(UIManager.getFont("Table.font").deriveFont(24f)); credits.setHorizontalAlignment(JLabel.CENTER); credits.setBorder(new CompoundBorder(new TitledBorder(""), new EmptyBorder(20,20,20,20))); dataPanel.showMessageLayer(credits, .75f); // DemoUtils.injectResources(XTableDemo.this, dataPanel); // wahscheinlich macht es credits.setText(... } // @Override //Use SwingWorker to asynchronously load the data // hide transparend overlay on end loading protected void done() { setProgress(100); dataPanel.hideMessageLayer(); } // } //------------------ init ui // JXTable display properties // center column header text private JXTable createXTable() { JXTable table = new JXTable() { @Override protected JTableHeader createDefaultTableHeader() { return new JXTableHeader(columnModel) { @Override public void updateUI() { super.updateUI(); // need to do in updateUI to survive toggling of LAF if (getDefaultRenderer() instanceof JLabel) { ((JLabel) getDefaultRenderer()).setHorizontalAlignment(JLabel.CENTER); } } // }; } }; return table; } protected Container createStatusBar() { JXStatusBar statusBar = new JXStatusBar(); statusBar.putClientProperty("auto-add-separator", Boolean.FALSE); // Left status area statusBar.add(Box.createRigidArea(new Dimension(10, 22))); statusBarLeft = Box.createHorizontalBox(); statusBar.add(statusBarLeft, JXStatusBar.Constraint.ResizeBehavior.FILL); actionStatus = new JLabel(); actionStatus.setName("loadingStatusLabel"); actionStatus.setText(getBundleString("loadingStatusLabel.text")); actionStatus.setHorizontalAlignment(JLabel.LEADING); statusBarLeft.add(actionStatus); // display progress bar while data loads progressBar = new JProgressBar(); statusBarLeft.add(progressBar); // Middle (should stretch) // statusBar.add(Box.createHorizontalGlue()); // statusBar.add(Box.createHorizontalGlue()); statusBar.add(Box.createVerticalGlue()); statusBar.add(Box.createRigidArea(new Dimension(50, 0))); // Right status area tableStatus = new JLabel(); tableStatus.setName("rowCountLabel"); tableStatus.setText(getBundleString("rowCountLabel.text")); JComponent bar = Box.createHorizontalBox(); bar.add(tableStatus); tableRows = new JLabel("0"); bar.add(tableRows); statusBar.add(bar); statusBar.add(Box.createHorizontalStrut(12)); return statusBar; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy