Chapter 17

advertisement
More on GUI
• We wrap up our examination of Java GUI
programming by looking at several other components
and their listeners
– The components all come from javax.swing
• We will look at JCheckBoxes, JRadioButtons,
JSliders, JSpinners, JComboBoxes, JLists,
JScrollBars, and how to open multiple windows
– Most have their own listeners although we do not
necessarily have to use these listeners, we could add
JButtons to activate an ActionListener which then can
obtain information from these components
– You can examine other GUI components from the author’s
online material (JMenu, JToolBar, JTabbedPane,
JSplitPane, JTree, and JTable)
JCheckBox and JRadioButton
• These classes extend the JToggleButton class which itself
(along with JButton) extend AbstractButton
• What these two types of buttons have in common is that
they will be in one of two states: selected or not selected
– check box allows any number of buttons to be selected
– radio button requires buttons be placed into a group where no
more than 1 button in a group is selected at a time
• Both can be created with strings and/or images and have hot
keys (mnemonics) associated with them
– to respond to a selected button, you can implement either
ActionListener or ItemListener to listen for an ItemEvent
• or you could add a JButton, say “Activate”, and in actionPerformed
obtain the status of every button (whether selected or not)
– code on the next few slides provides a demo for a program
which allows the user to format Graphics text, which is input
from a JTextField and is changed based on radio and check box
selections
import
import
import
import
java.awt.*;
java.awt.event.*;
javax.swing.*;
javax.swing.border.*;
public class GUIEventDemo extends JFrame {
private JLabel jlblMessage=new JLabel("Hello", JLabel.CENTER);
private JCheckBox jchkBold = new JCheckBox("Bold");
private JCheckBox jchkItalic = new JCheckBox("Italic");
private JRadioButton jrbRed = new JRadioButton("Red");
private JRadioButton jrbGreen = new JRadioButton("Green");
private JRadioButton jrbBlue = new JRadioButton("Blue");
private JTextField jtfMessage = new JTextField(10);
public static void main(String[] args) { // details omitted}
public GUIEventDemo() {
jlblMessage.setBorder(new LineBorder(Color.BLACK, 2));
add(jlblMessage, BorderLayout.CENTER);
JPanel jpCheckBoxes = new JPanel();
jpCheckBoxes.setLayout(new GridLayout(2, 1));
jpCheckBoxes.add(jchkBold);
jpCheckBoxes.add(jchkItalic);
add(jpCheckBoxes, BorderLayout.EAST);
JPanel jpRadioButtons = new JPanel();
jpRadioButtons.setLayout(new GridLayout(3, 1));
jpRadioButtons.add(jrbRed);
jpRadioButtons.add(jrbGreen);
jpRadioButtons.add(jrbBlue);
add(jpRadioButtons, BorderLayout.WEST);
ButtonGroup group = new ButtonGroup();
group.add(jrbRed); group.add(jrbGreen); group.add(jrbBlue);
jrbBlue.setSelected(true);
jlblMessage.setForeground(Color.blue);
JPanel jpTextField = new JPanel();
jpTextField.setLayout(new BorderLayout(5, 0));
jpTextField.add(new JLabel("Enter a new message"),
BorderLayout.WEST);
jpTextField.add(jtfMessage, BorderLayout.CENTER);
jtfMessage.setHorizontalAlignment(JTextField.RIGHT);
add(jpTextField, BorderLayout.NORTH);
jchkBold.setMnemonic('B'); jchkItalic.setMnemonic('I');
jrbRed.setMnemonic('E'); jrbGreen.setMnemonic('G');
jrbBlue.setMnemonic('U');
jchkBold.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setNewFont(); } });
jchkItalic.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setNewFont(); } });
jrbRed.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jlblMessage.setForeground(Color.red); } });
jrbGreen.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jlblMessage.setForeground(Color.green); } });
jrbBlue.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jlblMessage.setForeground(Color.blue); } });
jtfMessage.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jlblMessage.setText(jtfMessage.getText());
jtfMessage.requestFocusInWindow(); } }); }
private void setNewFont() {
int fontStyle = Font.PLAIN; fontStyle +=
(jchkBold.isSelected() ? Font.BOLD : Font.PLAIN);
fontStyle +=
(jchkItalic.isSelected() ? Font.ITALIC : Font.PLAIN);
Font font = jlblMessage.getFont();
jlblMessage.setFont( new Font(font.getName(), fontStyle,
font.getSize())); } }
ItemListener, ItemEvent
• The previous example used anonymous action listeners
• When you click on (or use a mnemonic hot key) any radio
button or check box, an ItemEvent occurs, and then an
ActionEvent occurs
• We could have also implemented ItemListener instead of
ActionListener
– For each of our buttons, we could replace the addActionListener
message with the following
• buttonname.addItemListener(new ItemListener( ) {
@override
public void itemStateChanged(ItemEvent e) {…} });
– The … code depends on whether the button is a check box (set
foreground color) or radio button (call setNewFont( );)
• we would leave the JTextField listener as is as pressing the enter key in a
text field generates an ActionEvent (also a TextEvent) but not an
ItemEvent
Implementing ItemListener
• Recall GUI2 which provided a GUI with JCheckBoxes
and JRadioButtons
• We will finish the GUI by making it respond when the
buttons are selected
• We will use an ItemListener so that for each selection,
an ItemEvent will be captured by the method
itemStateChanged
– We could also implement an ActionListener for a selection
or we could add a JButton
• The code on the next slide includes only the differences
from GUI2
– In order for the GUI to respond, we add a JLabel to output
what has been selected
– Since we can select multiple JCheckBoxes, the JLabel’s
output will be a concatenation of all items selected – thus
we make this String an instance datum
public static class GuiPanel extends JPanel
implements ItemListener { // Buttons declared
private JLabel lab;
// as with GUI2
private String message;
public GuiPanel() {
message="";
lab=new JLabel("
");
b1.addItemListener(this); // ... for all 7 buttons
JPanel whole=new JPanel(new BorderLayout());
whole.add(p1,BorderLayout.WEST);
whole.add(p2,BorderLayout.EAST);
whole.add(lab,BorderLayout.SOUTH);
add(whole);
}
public void itemStateChanged(ItemEvent e) {
if(e.getSource()==b1) message+="Option 1 selected ";
if(e.getSource()==b2) message+="Option 2 selected ";
if(e.getSource()==b3) message+="Option 3 selected ";
if(e.getSource()==b4) message+="Option 4 selected ";
if(e.getSource()==b5) message+="Selection a picked";
else if(e.getSource()==b6) message+="Selection b picked";
else if(e.getSource()==b7) message+="Selection c picked";
lab.setText(message);
}
}
Scroll Bars and Scroll Panes
• JScrollBars are added to JFrames
– When you instantiate a scroll bar you specify its orientation
(JScrollBar.HORIZONTAL or JScrollBar.VERTICAL)
– You can also specify the starting value, its min and max values (if
not specified, starting value by default is in the middle)
• Scroll bars will generate AdjustmentEvents which are listened
for by an AdjustmentListener
– To implement an AdjustmentListener, implement the method
adjustmentValueChanged
• The problem with a scroll bar added to the JFrame is moving
the view within the JFrame upon changing the scroll bar’s
“knob”
• Instead, we can also place our JPanel inside a scrollable
component called a JScrollPane – this will be easier
– Instantiate a JPanel for instance MyPanel p1 = new MyPanel( );
– Instantiate a JScrollPane using p1, JScrollPane jsp=new
JScrollPane(p1);
– Now the JPanel will have its own scroll bars if needed
import java.awt.*;
import javax.swing.*;
public class ScrollExample1 {
public static void main(String[] args) {
// JFrame code omitted
ScrollPanel p1=new ScrollPanel();
p1.setPreferredSize(new Dimension(250,100));
JScrollPane jsp=new JScrollPane(p1);
frame.add(jsp);
}
public static class ScrollPanel extends JPanel {
// code goes here for the JPanel
// for instance, maybe we want to draw something:
public void paintComponent(Graphics g) {
// Graphics code goes here
}
}
}
JTextBox and JTextArea
• Both extend JTextComponent
• They have methods to setText, getText, isEditable and
setEditable
– You can also set lineWrap to allow line wrapping (if true) and use a
wrapStyleWord to indicate if lines should be wrapped by word (if
true) or character (if false)
• The difference between these components is that the text area
has multiple rows
• You construct the text area using one of four constructors
–
–
–
–
empty
row, column size
String – the area defaults to roughly the size of the String
String, row, column size
• Additional methods to a text area are to append a String, insert
a String at a given index using jta.insert(String, index), replace
a portion of the text with a new String using
jta.replaceRange(String, start, end) and getLineCount
public static class ScrollPanel extends Jpanel {
private JLabel lab;
private JTextArea jta;
A JTextArea inside a JScrollPanel
public ScrollPanel()
{
lab=new JLabel("");
JTextArea jta=new JTextArea(5,50);
JScrollPane jsp=new JScrollPane(jta);
jta.setLineWrap(true); jta.setWrapStyleWord(true);
jta.getDocument().addDocumentListener(new DocumentListener(){
@Override
public void changedUpdate(DocumentEvent e){
lab.setText("changing text");
}
public void insertUpdate(DocumentEvent e) {
lab.setText("inserting");
}
public void removeUpdate(DocumentEvent e) {
lab.setText("deleting");
}
});
// insert jta and
// lab into JPanel
}
}
JComboBox
• Drop down menus must be added to a JFrame rather
than a JPanel so they are somewhat unusual and we
will skip covering them
• But Java does contain an alternate to a drop down
menu – a JComboBox
– The JComboBox allows you to select one item from a list
of items
– You define the list in an array of Objects when you
instantiate the JComboBox
• Upon selection, an ItemEvent and an ActionEvent
are created so you can either implement an
ItemListener (itemStateChanged) or ActionListener
– The JComboBox can be implemented so that the entire list
appears, only part of the list appears (along with a scroll
bar) or a drop-down box appears
public static class JCBPanel extends JPanel
implements ItemListener{
private JLabel lab;
private JComboBox box;
private String[] list={//…};
private String[] descr={//…};
}
public JCBPanel() {
lab=new JLabel("
");
box=new JComboBox<String>(list);
box.addItemListener(this);
setLayout(new BorderLayout());
add(box,BorderLayout.CENTER);
add(lab,BorderLayout.EAST);
}
public void itemStateChanged(ItemEvent e) {
lab.setText(descr[box.getSelectedIndex()]);
}
Other JComboBox methods are:
addItem(Object)
getItemAt(int)
getItemCount( )
getSelectedItem( ) – returns an Object
removeItem(Object)
removeItemAt(index)
JList
• The JList is similar to the JComboBox except that the
List appears in a box (no drop down action needed)
– The JList allows for multiple selections instead of the
single selection of a JComboBox
• the JList has an instance datum selectionMode which can be one
of SINGLE_SELECTION, SINGLE_INTERVAL_SELECTION
(you can select multiple items as long as they are contiguous in
the list) and MULTIPLE_INTERVAL_SELECTION (multiple
items whether contiguous or not)
• the default is for multiple items (to select multiple items, hold
down the control key while clicking, the shift key selects all items
between last and current item in list)
• If your JList is longer than the space in your JPanel,
add the JList to a JScrollPane and insert the
JScrollPane into your JPanel instead of the JList
– This provides you a scroll bar as needed to view the whole
list
More on JList
• The JList will use a ListSelectionListener (defined in
javax.swing.event instead of java.awt.event) for any
changes to the list (selecting or unselecting items)
– Such a change generates a ListSelectionEvent
– The ListSelectionListener must implement a valueChanged
method
• Since a JList can have multiple selected items, there are
methods that return single Objects or ints (selected items,
selected item indices) or arrays
– single value methods: getMaxSelectionIndex,
getMinSelectionIndex, getLeadSelectionIndex, getSelectedValue
(returns the smallest index of the selected)
– array methods: getSelectedIndices, getSelectedValues
public void valueChanged(ListSelectionEvent e) {
int[] x=list.getSelectedIndices();
for(int i=0;i<x.length;i++)
// do something with x[i]
}
JSlider
• The JSlider, which can be positioned horizontally or
vertically, gives you an input for an int value between
a min an max value
– The JSlider is usually instantiated with min and max
values, or min, max and the starting value of the slider
(e.g., 0,100,50 would set the slider at 50)
– Orientation is specified using JSlider.HORIZONTAL (the
default) or JSlider.VERTICAL
• you can also specify if tick marks should appear or not by setting
paintTicks to true (defaults to false) and setting paintLabels to
true (to print labels with the tick marks)
– The JSlider creates a ChangeEvent which is handled by a
ChangeListener through the stateChanged method
– In this method, to determine the location of the slider, use
slider.getValue( ) (where slider is the name of your object)
import java.awt.*;
import javax.swing.event.*;
import javax.swing.*;
public class JSL {
public static void main(String[] args)
{ // omitted }
public static class SliderPanel extends JPanel
implements ChangeListener {
private JSlider s1, s2, s3;
private int red, green, blue;
public SliderPanel() {
red=0;green=0;blue=0;
s1=new JSlider(0,255,0);s2=new JSlider(0,255,0);
s3=new JSlider(0,255,0);s1.addChangeListener(this);
s2.addChangeListener(this);s3.addChangeListener(this);
JPanel p1=new JPanel(new GridLayout(3,1));
p1.add(s1); p1.add(s2); p1.add(s3); add(p1);
}
public void stateChanged(ChangeEvent e) {
if(e.getSource()==s1) red=s1.getValue();
if(e.getSource()==s2) green=s2.getValue();
if(e.getSource()==s3) blue=s3.getValue();
repaint();
}
public void paintComponent(Graphics g) {…}
}
}
Controlling Multiple Windows
• You can create and open/close other windows easily
by declaring additional JFrames
– Once a JFrame is created, use frame.setVisible(true); to
open it and frame.setVisible(false); to close it
• Let’s imagine that you want a program that can open
another window on command (we will use JButtons
to open and close a second window)
– Create an instance datum in your JPanel (inner class) of
type JFrame
– In this inner JFrame class, define another JPanel
• this JPanel will display the contents of the newly opened window,
whatever that will be
– In your JPanel, add two JButtons
– For actionPerformed, one button will set the inner class’
JFrame to visible and the other will set the inner class’
JFrame to not visible
public static class ButtonPanel extends JPanel
implements ActionListener {
private JFrame second=new JFrame();
private SecondPanel sp=new SecondPanel();
private JButton b1, b2;
public ButtonPanel(){
second.setSize(new Dimension(200,200));
second.add(sp);
b1=new JButton("open second window");
b2=new JButton("close second window");
b1.addActionListener(this);
b2.addActionListener(this);
add(b1);
add(b2);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==b1) second.setVisible(true);
else if(e.getSource()==b2) second.setVisible(false);
}
private class SecondPanel extends JPanel{
public void paintComponent(Graphics g) {
g.setColor(Color.green); g.fillRect(0,0,200,200);
}
}
Download