500 likes | 653 Views
Algorithm Programming 1 JAVA GUI with Swing. Bar-Ilan University 2006-2007 תשס"ז Moshe Fresko. AWT. AWT : Abstract Windowing Toolkit. Tools for developing Platform Independent GUI. AWT rely on native C code to create User Interface components. Java 1.0 AWT : Very restrictive.
E N D
Algorithm Programming 1 JAVA GUI with Swing Bar-Ilan University 2006-2007 תשס"ז Moshe Fresko
AWT • AWT : Abstract Windowing Toolkit. Tools for developing Platform Independent GUI. • AWT rely on native C code to create User Interface components. • Java 1.0 AWT : Very restrictive. • Java 1.1 AWT : Event Model, more OO approach • Java 2 (JDK 1.2) – Everything replaced by JFC (Java Foundation Classes). • Swing: GUI part of JFC.
Swing • Swing is a powerful collection of UI components. • Multiple look and feel support • Customizable look and feel • Lightweight UI framework • Swing components are written in pure Java (uses AWT components which use native C codes) • MVC (Model View Controller) style component designs
Some Swing libraries • javax.swing.* : Includes swing GUI components and supporting classes. • javax.swing.border.* : Classes that defines borders to decorate GUI components. • javax.swing.event.* : Event handling classes, including new event and listener classes • javax.swing.plaf.* : Definitions of UI objects for the Swing components • javax.swing.table.* : Supporting classes for the Table component • javax.swing.text.* : The swing styled text framework • javax.swing.tree.* : Supporting classes for the Tree component
JComponent • Most of the Swing components are subclasses of JComponent. • JComponent is the root of “COMPOSITE” pattern. • JComponent is a “Container” which has .add(Component) method. java.lang.Object java.awt.Component java.awt.Container javax.swing.JComponent JButton JPanel JLabel JComboBox
Example Window import javax.swing.* ; import java.awt.event.* ; import java.awt.* ; public class SimpleWindow { public static void main(String s[]) { JFrame frame = new JFrame("Simple Window") ; JButton button = new JButton("Hello Button") ; JLabel label = new JLabel("A Label") ; frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ; frame.getContentPane().add(button,"Center") ; frame.getContentPane().add(label,"South") ; frame.pack() ; frame.setVisible(true) ; } }
JComponent features • JComponent defines some standard features for Swing components • Borders • Component-specified min.,max., and preferred sizes • Tool tips • Slow-motion rendering for Debugging • Auto-scrolling • Double buffering • Keystroke handling • Support for accesibility • Actions • Icons
JComponent features • Example: • public void setBorder(Border aBorder) • public Dimension getMinimumSize()public Dimension getMaximumSize()public Dimension getPreferredSize() • public void setToolTipText(String txt) • public void setAutoscrolls(boolean yesNo) • public void registerKeyboardAction(ActionListener anAction, KeyStroke aKeyStroke, int aCondition) • etc.
Pattern: “Composite” • Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly. • Example: Graphical components. Containers can have many Simple components and other Containers. • From Client Side: No distinction between Simple Components to Containers.
Event Handling • Delegation event model. • Event types • Event processors • Event listeners Event Event Processor / Component Registers Notifies Event Listener
Event Types • Event Types • ActionEvent : Like Button clicked or the return key is pressed. • ChangeEvent : A value has changed. • FocusEvent : Component gains or looses focus. • ItemEvent : Selection of an item changed. • KeyEvent : Key press or release • ListDataEvent : Contents of a list change • ListSelectionEvent : Selection in list changes • MenuEvent : When a menu is selected or cancelled • MouseEvent : • WindowEvent : Window closing, iconifying, etc.
Event Listeners • Customized programs for reacting to events.Like : What to do when a button is clicked. • One Event Processor can have more then one event listener.Like : There can be a couple of Listeners for a button click. • Components that react to events must implement the appropriate interface.Like : In Button-click, the reacting object must be an implementation of ActionListener • There are adaptors for making Concrete empty implementation of Listeners.
Events in Swing • If we have an event called EEE • Event addition-removal functions are located mostly in JComponent typesaddEEEListener(EEEListener listener)removeEEEListener(EEEListener listener) • The Listener interface type is interface EEEListener • The Abstract class of that interface (if there is one) isabstract class EEEAdapter • The Event get is in the object of class EEEEvent
Events in swing • Event Class = ActionEventListener Interface = ActionListenerFunctions = addActionListener(…) removeActionListener(…)No Adapter.Who : JButton, JList, JTextField, JMenuItem, etc. • Event Class = AdjustmentEventListener Interface = AdjustmentListenerFunctions = addAdjustmentListener(…) removeAdjustmentListener(…)No Adapter.Who : JScrollbar • Event Class = WindowEventListener Interface = WindowListenerFunctions = addWindowListener(…) removeWindowListener(…)No Adapter.Who : JFrame, JDialog, JFileDialog, etc. • Many more: ComponentEvent, ContainerEvent, FocusEvent, KeyEvent, MouseEvent, ItemEvent, TextEvent, etc.
Example: Window with Event Handler public class Windows extends JFrame { public static void main(String[] args) { JFrame win = new Windows() ; win.addWindowListener(new WindowCloser()) ; win.getContentPane().add(new Label("Hello"),"Center") ; win.pack() ; win.setVisible(true) ; } } import java.util.* ; import java.awt.* ; import java.awt.event.* ; import javax.swing.* ; class WindowCloser extends WindowAdapter // Indirectly implements WindowListener { int i = 0 ; public void windowClosing(WindowEvent e) { Window win ; i++ ; if (i>=3) { win = e.getWindow() ; win.setVisible(false) ; win.dispose() ; System.exit(0) ; } } }
Example: Button with Action Event package GUI; import java.awt.* ; import java.awt.event.* ; import javax.swing.* ; public class HelloGoodbye extends JFrame implements ActionListener { private static final String HELLO="Hello!" ; private static final String GOODBYE="GoodBye!" ; private String message = HELLO ; private JPanel counterPanel ; private JButton counterButton ; private JLabel counterLabel ; public HelloGoodbye() { super("HelloGoodbye") ; counterLabel = new JLabel(message,SwingConstants.CENTER) ; counterButton = new JButton("Click Me") ; counterButton.addActionListener(this) ; counterPanel = new JPanel() ; counterPanel.setBorder( BorderFactory. createEmptyBorder(20,60,20,60)) ; counterPanel.setLayout(new BorderLayout()) ; counterPanel.add( counterLabel,BorderLayout.CENTER) ; counterPanel.add( counterButton,BorderLayout.SOUTH) ; getContentPane().add(counterPanel) ; addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0) ; } } ) ; pack() ; setVisible(true) ; } public void actionPerformed(ActionEvent e) { if (message.equals(HELLO)) { message = GOODBYE ; } else { message = HELLO ; } counterLabel.setText(message) ; } public static void main(String[] args) { final HelloGoodbye app = new HelloGoodbye() ; } }
Event Queue • Event Occurs • Event Object Created • Add Event to Queue Event Event Queue Notifiy Processor / Component Get Next Event Determine Event Processor
Layout Managers • Layout managers define how to lay out the child components in a container. • Each container type has a default Layout manager. • It can be replaced with an existing layout manager or a custom one can be created.
Layout Managers • Some layout Managers in AWT and Swing • BorderLayout • BoxLayout • CardLayout • FlowLayout • GridBagLayout • GridLayout • OverlayLayout • ScrollpaneLayout • ViewportLayout • Some containers have default layout managers • JPanel : FlowLayout • JScrollPane : ScrollPaneLayout • JViewport : ViewportLayout • etc.
import javax.swing.*; import java.awt.*; public class BorderLayoutExample { public static void main(String[] args) { JFrame f = new JFrame("Border Layout Example") ; Container c = f.getContentPane() ; c.setLayout(new BorderLayout()) ; // Default c.add(BorderLayout.NORTH, new JButton("North")); c.add(BorderLayout.SOUTH, new JButton("South")); c.add(BorderLayout.EAST, new JButton("East")); c.add(BorderLayout.WEST, new JButton("West")); c.add(BorderLayout.CENTER, new JButton("Center")); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ; f.pack() ; f.setVisible(true) ; } } Border Layout Example
Flow Layout Example import javax.swing.*; import java.awt.*; public class FlowLayoutExample { public static void main(String[] args) { JFrame f = new JFrame("Flow Layout Example") ; Container c = f.getContentPane() ; c.setLayout(new FlowLayout()) ; c.add(new JButton("North")); c.add(new JButton("South")); c.add(new JButton("East")); c.add(new JButton("West")); c.add(new JButton("Center")); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ; f.pack() ; f.setVisible(true) ; } }
MVC • MVC : (Model View Controller) is used in building User Interfaces. • MVC consists of three kinds of objects • Model : Is the application object, or data. • View : Its screen presentation • Control : Controls how User interface reacts with the data. • MVC uses subscribe/notify protocol. • Decoupling between Model and View, allows to attach Multiple Views to a Model.
Example - Swing • Swing components has Model-View-Controller type of organization. • For example : • JProgressBar uses BoundedRangeModel. • public BoundedRangeModel getModel() ; • public void setModel(BoundedRangeModel newModel) ; • JSlider as well uses BoundedRangeModel.
Example – BoundedRangeModel public static void main(String[] args) { JFrame f = new JFrame("Progress Model Example") ; ProgressModel panel = new ProgressModel() ; f.setForeground (Color.black) ; f.setBackground (Color.lightGray) ; f.setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE ) ; f.getContentPane().add ( BorderLayout.CENTER,panel) ; f.setSize(panel.getPreferredSize()) ; f.show() ; } } import java.util.* ; import java.awt.* ; import java.awt.event.* ; import javax.swing.* ; public class ProgressModel extends JPanel { public ProgressModel() { JProgressBar progBar = new JProgressBar() ; progBar.setMinimum(0) ; progBar.setMaximum(100) ; progBar.setValue(0) ; JSlider slider = new JSlider() ; slider.setModel(progBar.getModel()) ; add(progBar) ; add(slider) ; } public Dimension getPreferredSize() { return new Dimension(300,100) ; }
“OBSERVER” Pattern • Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. • The key objects are “subject” and “observer”. • A “subject” can have many dependent “observer”s • Whenever “suject” undergoes a change all “observer”s are notified • Each “observer” can query “subject” for synchronizing its state • “Publish”-“Subscribe” : “observer”s are subscribed to “subject” and “subject” publishes or notifies the observers of any change.
OBSERVER • Participants • “Subject” • Knows its observers. • Methods for adding and removing “Observer”s • “Observer” • Method for being updated • ConcreteSubject • Stores state of interest • Sends notification to “Observer”s when its state change • ConcreteObserver • Has a reference to ConcreteSubject • Its state must be consistent with subject’s state • Implements Updating to keep its state consistent with subject’s state
OBSERVER • Who calls notify() or update() … • If Subject calls … • Client Observers don’t have to remember to call every time there is a change in Subject • If Observers call • An Observer can make a list of changes and only then call the notify() • Update() can pass as argument the change. • Push model : Subject sends observers detailed information about the change, whether they want it or not. • Pull model : Subject sends only a minimal notification, and observers ask for details. • Observers can specify interest on some changes when they subscribe.
JTree • A tree is a set of hierarchical nodes. • The top of this hierarchy is called “root”. • An element that does not have children is called “leaf”. • JTree nodes are managed by a “TreeModel”. • “TreeCellRenderer” converts an object to its visual representation in the tree.
TreeModel Methods • Object getRoot() • Object getChild(Object parent, int index) • int getChildCount(Object parent) • boolean isLeaf(Object node) • void valueForPathChanged(TreePath path, Object newVal) • int getIndexOfChild(Object parent, Object child) • void addTreeModelListener(TreeModelListener l) • void removeTreeModelListener(TreeModelListener l)
JTree constructors • JTree() • JTree(Object[] value) • JTree(Vector value) • JTree(Hashtable value) • JTree(TreeNode root) • JTree(TreeNode root, boolean asksAllowsChildren) • JTree(TreeModel newModel)
Default tree model uses objects of TreeNode to represent the nodes in the tree. A default implementation of it is DefaultMutableTreeNode. TreeNode methods TreeNode getChildAt(int childIndex) int getChildCount() TreeNode getParent() int getIndex(TreeNode node) boolean getAllowsChildren() boolean isLeaf() Enumeration children() DefaultMutableTreeNode constructors DefaultMutableTreeNode() DefaultMutableTreeNode(Object userObject) DefaultMutableTreeNode(Object userObject, boolean allowsChildren) TreeNodes
JTree example public Dimension getPreferredSize() { return new Dimension(200,120) ; } public static void main(String[]args) { JFrame frame = new JFrame("Tree Node Example") ; TreeNodeExample panel = new TreeNodeExample() ; frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ; frame.getContentPane().add(panel,"Center") ; frame.setSize(panel.getPreferredSize()) ; frame.setVisible(true) ; } } import javax.swing.* ; import javax.swing.tree.* ; import java.awt.event.* ; import java.awt.* ; import java.util.* ; public class TreeNodeExample extends JPanel { public TreeNodeExample() { DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Categories") ; DefaultMutableTreeNode parentNode = new DefaultMutableTreeNode("Metals") ; parentNode.add(new DefaultMutableTreeNode("Gold",false)) ; parentNode.add(new DefaultMutableTreeNode("Silver",false)) ; parentNode.add(new DefaultMutableTreeNode("Bronze",false)) ; parentNode.add(new DefaultMutableTreeNode("Copper",false)) ; parentNode.add(new DefaultMutableTreeNode("Iron",false)) ; parentNode.add(new DefaultMutableTreeNode("Platinium",false)) ; parentNode.add(new DefaultMutableTreeNode("Titanium",false)) ; rootNode.add(parentNode) ; parentNode = new DefaultMutableTreeNode("Companies") ; parentNode.add(new DefaultMutableTreeNode("Paradigm Research",false)) ; parentNode.add(new DefaultMutableTreeNode("JavaSoft",false)) ; parentNode.add(new DefaultMutableTreeNode("Wiley Press",false)) ; rootNode.add(parentNode) ; setLayout(new BorderLayout()); add(new JScrollPane(new JTree(rootNode)),"Center") ; }
TreeModel Listener • TreeModelListener methods • void treeNodesChanged(TreeModelEvent e) • void treeNodesInserted(TreeModelEvent e) • void treeNodesRemoved(TreeModelEvent e) • void treeStructureChanged(TreeModelEvent e) • TreeModelEvent methods • TreePath getTreePath() • Object[] getPath() • Object[] getChildren() • int[] getChildIndices()
Custom Tree Model Example import java.io.* ; import java.util.* ; class FileHolder { File myFile ; Vector children ; public FileHolder(File f) { myFile = f ; } public File getFile() { return myFile ; } public String toString() { return myFile.getName() ; } public Vector getChildren() { if (myFile.isDirectory() && (children==null)) { int max=0; String list[] ; File curFile ; FileHolder curHolder ; children = new Vector() ; list = myFile.list() ; if (list!=null) max = list.length ; for (int i=0;i<max;++i) { curFile = new File(myFile,list[i]) ; curHolder = new FileHolder(curFile) ; children.addElement(curHolder) ; } } return children ; } }
Custom Tree Model Example public boolean isLeaf(Object node) { boolean retVal = true ; File file ; if (node instanceof FileHolder) { file = ((FileHolder)node).getFile() ; retVal = file.isFile() ; } return retVal ; } public void valueForPathChanged(TreePath path, Object newVal) { } public int getIndexOfChild(Object parent, Object child) { int retVal = -1 ; Vector children ; if (parent instanceof FileHolder) { children = ((FileHolder)parent).getChildren() ; if (children!=null) retVal = children.indexOf(child) ; } return retVal ; } public void addTreeModelListener(TreeModelListener l) { if ((l!=null)&&!listeners.contains(l)) listeners.addElement(l) ; } public void removeTreeModelListener(TreeModelListener l) { listeners.removeElement(l) ; } } import javax.swing.* ; import javax.swing.tree.* ; import javax.swing.event.* ; import java.io.* ; import java.util.* ; class FileSystemTreeModel implements TreeModel { protected FileHolder root ; protected Vector listeners ; public FileSystemTreeModel(File r) { root = new FileHolder(r) ; listeners = new Vector() ; } public Object getRoot() { return root ; } public Object getChild(Object parent, int index) { Object retVal=null ; Vector children ; if (parent instanceof FileHolder) { children = ((FileHolder)parent).getChildren() ; if (children!=null) if (index<children.size()) retVal=children.elementAt(index) ; } return retVal ; } public int getChildCount(Object parent) { int retVal = 0 ; Vector children ; if (parent instanceof FileHolder) { children = ((FileHolder)parent).getChildren() ; if (children!=null) retVal = children.size() ; } return retVal ; }
Custom Tree Model Example import javax.swing.* ; import java.awt.event.* ; import java.awt.* ; import java.io.* ; import java.util.* ; public class FileTree extends JPanel { public FileTree(String startPath) { JTree tree = new JTree() ; tree.setModel(new FileSystemTreeModel(new File(startPath))) ; setLayout(new BorderLayout()) ; add(new JScrollPane(tree),"Center") ; } public Dimension getPreferredSize() { return new Dimension(250,200) ; } public static void main(String[]s) { JFrame frame = new JFrame("File Tree Example") ; FileTree panel = new FileTree(s.length>0?s[0]:"/") ; frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) ; frame.getContentPane().add(panel,"Center") ; frame.setSize(panel.getPreferredSize()) ; frame.setVisible(true) ; } }
JTable • JTable displays tabular data in rows and columns. • Header for the title of each column.
TableModel • TableModel Methods • void addTableModelListener(TableModelListener l) • void removeTableModelListener(TableModelListener l) • int getRowCount() • int getColumnCount() • String getColumnName(int columnIndex) • Class getColumnClass(int columnIndex) • boolean isCellEditable(int rowIndex, int columnIndex) • Object getValueAt(int rowIndex, int columnIndex) • Object setValueAt(Object aValue, int rowIndex, int columnIndex) • AbstractTableModel (methods that must be implemented) • int getRowCount() • int getColumnCount() • Object getValueAt(int rowIndex,int columnIndex)
TableModelListener • TableModelListener methods • void tableChanged(TableModelEvent evt) • TableModelEvent methods • int getColumn() • int getFirstRow() • int getLastRow() • int getType()