Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Professional Java.JDK.5.Edition (Wrox)

.pdf
Скачиваний:
31
Добавлен:
29.02.2016
Размер:
12.07 Mб
Скачать

Chapter 4

table = new JTable(mtm); table.setPreferredScrollableViewportSize(new Dimension(250, 70)); JScrollPane scrollPane = new JScrollPane(table); tablePanel.add(scrollPane);

table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); ListSelectionModel rowSM = table.getSelectionModel(); rowSM.addListSelectionListener(new ListSelectionListener() {

public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) return;

lsm = (ListSelectionModel) e.getSource(); if (lsm.isSelectionEmpty()) {

//no rows are selected } else {

selectedRow = lsm.getMinSelectionIndex(); logger.info(“selectedRow= “ + selectedRow);

}

}

});

return tablePanel;

}

The formPanel() method implements a SpringLayout manager where all of the log entry components are placed so that user training activities can be tracked. Two Swing library layout managers, BorderLayout and GridLayout, are combined so that a SpringLayout manager that holds the triathlon training attributes can be placed above the Save and Cancel buttons:

public JPanel formPanel() {

springLayout = new SpringLayout(); panelInput = new JPanel(springLayout);

panelInput.setMinimumSize(new Dimension(350, 370)); panelInput.setPreferredSize(new Dimension(350, 370));

eventPanel = new JPanel(); eventPanel.setLayout(new BorderLayout());

eventPanel.setPreferredSize(new Dimension(350, 400));

panelButton = new JPanel(); panelButton.setLayout(new GridLayout(1, 4));

panelButton.setMinimumSize(new Dimension(350, 30)); panelButton.setPreferredSize(new Dimension(350, 30));

textareaDescription = new JTextArea();

buttonSave = new JButtonSave(); buttonCancel = new JButtonCancel();

comboboxTime = new JComboBox();

trainingLength = new String[] { “15 min”, “30 min”, “45 min”, “1 hr”, “2 hrs”

};

comboboxLength = new JComboBox(trainingLength);

186

Developing Effective User Interfaces with JFC

textfieldTitle = new JTextField();

category = new String[] { “Swim”, “Bike”, “Run”, “Other” }; comboboxCategory = new JComboBox(category);

model = new SpinnerDateModel(); model.setCalendarField(Calendar.WEEK_OF_MONTH); spinner = new JSpinner(model); JSpinner.DateEditor editor =

new JSpinner.DateEditor(spinner, “MMMMM dd, yyyy”); spinner.setEditor(editor);

ChangeListener listener = new ChangeListener() { public void stateChanged(ChangeEvent e) {

SpinnerModel source = (SpinnerModel) e.getSource(); System.out.println(“The value is: “ + source.getValue());

}

};

model.addChangeListener(listener);

// label declarations and initializations for Title, Date, Category, Time, Duration, and Description omitted for better clarity

The code segment below establishes two button components and a text area display for the triathlon entry form. The text area named textareaDescription is enabled and has an etched border frame to surround it. Minimum and maximum size constraints are defined as well as column values and line wrapping so that text entered by a user remains in sight of that user. Buttons for both the save and cancel operations have text labels attached to them with new font declarations and tool tip text for mouse over pop-ups that indicate what purpose those buttons serve:

textareaDescription.setEnabled(true);

textareaDescription.setBorder(BorderFactory.createEtchedBorder()); textareaDescription.setMinimumSize(new Dimension(85, 51)); textareaDescription.setPreferredSize(new Dimension(85, 51)); textareaDescription.setText(“”); textareaDescription.setColumns(25); textareaDescription.setLineWrap(true);

buttonSave.setText(“Save event”); buttonSave.setFont(new java.awt.Font(“Dialog”, 1, 12)); buttonSave.addActionListener(this); buttonSave.setToolTipText(“Save event.”); buttonSave.setPreferredSize(new Dimension(58, 25));

buttonCancel.setText(“Return to event list.”); buttonCancel.setFont(new java.awt.Font(“Dialog”, 1, 12)); buttonCancel.addActionListener(this); buttonCancel.setToolTipText(“Return to event list.”); buttonCancel.setPreferredSize(new Dimension(58, 25));

The following code segment dictates how to implement SpringLayout constraints to achieve the look and feel of the disparate Swing components for tracking. The Constraints object of the SpringLayout manager positions the edges of the children in the container object through vertical and horizontal values:

187

Chapter 4

//Add the components to the panel using SpringLayout. panelInput.add(labelTitle,new

SpringLayout.Constraints(Spring.constant(15),Spring.constant(21)));

panelInput.add(textfieldTitle,new

SpringLayout.Constraints(Spring.constant(45),Spring.constant(17)));

panelInput.add(labelTime,new

SpringLayout.Constraints(Spring.constant(13),Spring.constant(69)));

panelInput.add(comboboxTime,new

SpringLayout.Constraints(Spring.constant(45),Spring.constant(63)));

panelInput.add(labelLength,new

SpringLayout.Constraints(Spring.constant(190),Spring.constant(69)));

panelInput.add(comboboxLength,new

SpringLayout.Constraints(Spring.constant(250),Spring.constant(63)));

panelInput.add(labelCategory,new

SpringLayout.Constraints(Spring.constant(190),Spring.constant(115)));

panelInput.add(comboboxCategory,new

SpringLayout.Constraints(Spring.constant(250),Spring.constant(109)));

panelInput.add(labelDate,new

SpringLayout.Constraints(Spring.constant(15),Spring.constant(115)));

panelInput.add(spinner,new

SpringLayout.Constraints(Spring.constant(45),Spring.constant(111)));

panelInput.add(textareaDescription,new

SpringLayout.Constraints(Spring.constant(10),Spring.constant(217)));

panelInput.add(labelDescription,new

SpringLayout.Constraints(Spring.constant(11),Spring.constant(201)));

for (int i = 0; i < 24; i++) { timeString = Integer.toString(i); if (timeString.length() == 1)

timeString = “0” + timeString; if (i != 0) {

comboboxTime.addItem(timeString + “00”); comboboxTime.addItem(timeString + “15”); comboboxTime.addItem(timeString + “30”); comboboxTime.addItem(timeString + “45”);

} else {

comboboxTime.addItem(timeString + “00”); comboboxTime.addItem(timeString + “15”); comboboxTime.addItem(timeString + “30”); comboboxTime.addItem(timeString + “45”);

}

}

comboboxTime.addItem(“2400”);

comboboxTime.setSelectedItem(“0930”);

eventPanel.add(BorderLayout.CENTER, panelInput); eventPanel.add(BorderLayout.SOUTH, panelButton);

JPanel ePanel = new JPanel(new BorderLayout()); ePanel.add(eventPanel, BorderLayout.CENTER);

panelButton.add(buttonSave);

panelButton.add(buttonCancel);

188

Developing Effective User Interfaces with JFC

return ePanel;

}

The JAddEventButton class handles mouse events on the first tabbed pane display that occur when the user clicks the Add Event button on the bottom of the display. The application polymorphically invokes the execute() method, which removes all of the current panel components with the removeAll() method, and then creates a new layout so that the SpringLayout manager can be applied from the formPanel() method:

class JAddEventButton extends JButton implements Command { public JAddEventButton() {

super();

}

public void execute() { logger.info(“[JAddEventButton:execute]”); eventPanel.removeAll(); eventPanel.setLayout(new BorderLayout()); eventPanel.add(formPanel()); eventPanel.requestFocusInWindow(); eventPanel.validate();

}

}

The JButtonSave component handles user events that occur when the user clicks the Save Event button. A cursory data check is performed on the title field to ensure that a proper title has been entered by the user prior to moving back to the initial tabbed panel screen with the user entry displayed in a JTable component:

class JButtonSave extends JButton implements Command { public JButtonSave() {

super();

}

public void execute() {

if (textfieldTitle.getText().length() == 0 || textfieldTitle.getText() ==

null) {

Toolkit.getDefaultToolkit().beep(); JOptionPane.showMessageDialog(null, “Please Enter Event Title”,

“Error”, JOptionPane.ERROR_MESSAGE); textfieldTitle.requestFocusInWindow(); textfieldTitle.selectAll();

return;

}

JOptionPane.showMessageDialog(null, “Event saved.”, “Operation Completed”,

JOptionPane.INFORMATION_MESSAGE);

restoreLogPanel();

String[] s = { “”, “”, “”, “” };

s[0] = (String) comboboxCategory.getSelectedItem(); s[1] = textareaDescription.getText();

s[2] = (String) comboboxTime.getSelectedItem();

189

Chapter 4

mtm.populateTable(s);

}

}

class JButtonCancel extends JButton implements Command { public JButtonCancel() {

super();

}

public void execute() {

logger.info(“[JButtonCancel:execute] date = “ + getDate()); restoreLogPanel();

}

}

The getDate() method returns a string value from the JSpinner component that represents the date affiliated with the triathlon event. The restoreLogPanel() method invokes the removeAll() method to clear the panel display, establishes a new BorderLayout presentation panel, and initializes that new panel with the triathlon event components for logging operations. The requestFocusInWindow() method is called to request that the panel component gets the input focus. Lastly, the validate() method is implemented to cause the container to lay out its subcomponents again:

public String getDate() {

return ((JSpinner.DateEditor) spinner.getEditor()).getTextField().getText();

}

public void restoreLogPanel() { removeAll();

setLayout(new BorderLayout()); initComponents(); requestFocusInWindow(); validate();

}

public void actionPerformed(ActionEvent e) { Command obj = (Command) e.getSource(); obj.execute();

}

// main method omitted for better clarity

}

Figure 4-12 represents the SpringLayoutPanel tabbed panel application that appears on the user display when a user invokes the Add Event button. The form display performs a cursory check on the data to ensure proper data is entered by the user when the Save Event button is clicked. The SpringLayout manager distributes JTextfield, JComboBox, JSpinner, and JTextArea components using constraint values positioning.

190

Developing Effective User Interfaces with JFC

Figure 4-12

CardLayout

The CardLayout manager organizes its components as a stack of cards, where components are displayed one at a time. This allows components to be easily swapped in and out like a slide show presentation. The constructor methods for the CardLayout manager are shown in the method summary table below.

Method

Description

 

 

 

public

CardLayout()

No parameters

public

CardLayout(int hGap,

Constructor where the hGap and vGap parameters

int vGap)

specify the horizontal and vertical pixels between

 

 

components

 

 

 

The following CardLayout example employs the Command and Strategy patterns to encapsulate behavior that will be applied to the user text. Figure 4-13 shows the CardLayout model and the different Swing components applied to that layout manager panel.

191

Chapter 4

CardLayout

cards

 

 

 

JPanel

card1

Command pattern: execute()

JLabel1

 

JTextField1

JButton

JButton

JButton

 

 

 

 

 

swap

JPanel

card2

Command pattern: execute()

JLabel2

 

JTextField2

JButton

JButton

JButton

 

Strategy #1

 

Strategy #2

 

Strategy pattern : StartsWithAEIOU

Strategy pattern : AlphabeticChars

JPanel

results

JLabel

 

 

 

 

 

Figure 4-13

 

 

 

 

 

The CardLayoutPanel application utilizes the Strategy pattern to apply different algorithms to user specified text. The Command pattern is used to polymorphically determine what strategy to apply during run time. Some of the benefits and drawbacks of these two patterns are shown in the following table.

Pattern

Benefits

Consequences

 

 

 

Strategy

Decouples algorithms so that programs

Increases number of objects

 

can be more flexible in their execution of

 

 

logic and behavior

 

 

Reduces multiple conditional statements

 

 

 

 

The CardLayoutPanel source code follows to demonstrate how the model in Figure 4-13 can be developed:

[CardLayoutPanel.java]

// package name and import statements omitted

public class CardLayoutPanel extends JPanel implements ActionListener, ItemListener

{

// declarations omitted for the sake of brevity [Please check download code]

The CardLayoutPanel constructor lays out the manager for the two card panels, card1 and card2. The card1 panel contains two independent buttons that implement the Strategy pattern on user specified

192

Developing Effective User Interfaces with JFC

text. The card2 panel reveals the text that results from the State pattern algorithm application. The JButtonStrategy1 class applies the Pig-Latin algorithm to the use text when solicited by the user. The JButtonStrategy2 button converts the user text to uppercase text by applying the AlphabeticChars algorithm in its operations:

public CardLayoutPanel() {

setSize(700, 150);

cards = new JPanel(new CardLayout()); card1 = new JPanel();

card2 = new JPanel(); card3 = new JPanel();

//swap buttons swapButton1.addActionListener(this); swapButton1.setActionCommand(“Swap to Strategy 2”); swapButton2.addActionListener(this); swapButton2.setActionCommand(“Swap to Strategy 1”);

//Strategy Buttons strategyButton1.setActionCommand(“Strategy #1”); strategyButton1.addActionListener(this); strategyButton2.setActionCommand(“Strategy #2”); strategyButton2.addActionListener(this);

//Clear button clearButton1.setActionCommand(“clear”); clearButton1.addActionListener(this); clearButton2.setActionCommand(“clear”); clearButton2.addActionListener(this);

topPanel1.add(labelText1);

topPanel1.add(textfield1);

topPanel1.add(strategyButton1);

topPanel1.add(clearButton1);

topPanel1.add(swapButton1);

topPanel2.add(labelText2);

topPanel2.add(textfield2);

topPanel2.add(strategyButton2);

topPanel2.add(clearButton2);

topPanel2.add(swapButton2);

messageText = new JLabel(“Enter messages”); results.add(messageText); results.setPreferredSize(new Dimension(700, 100));

results.setBorder(BorderFactory.createLineBorder (Color.blue, 2)); results.setBackground(DIGIT_COLOR);

card1.add(topPanel1);

card2.add(topPanel2);

cards.add(cardText[0], card1);

193

Chapter 4

cards.add(cardText[1], card2);

card3.add(results, “Results Panel”);

add(cards);

add(card3);

}

The CardLayoutPanel class implements the ActionListener interface so that component objects created with that class can be registered using the addActionListener(ActionListener l) method shown in the previous code segment. The actionPerformed(ActionEvent e) method then processes those requests that are registered through the action listener. All of the JButton components in CardLayoutPanel implement the Command pattern interface method named execute() so that the appropriate button control method logic is executed when the user clicks that component. This is feasible because the application uses the object reference to that execute() method for execution. If one of the swap buttons is selected, then the sample application will alternate between strategy operations. The CardLayout next method is implemented to swap operations, but alternative code that performs that same operation using the swapNumber token and the CardLayout show method also demonstrate how to swap layouts:

public void actionPerformed(ActionEvent e) { if (e.getActionCommand.startsWith(“Swap”)) {

CardLayout cardLayout = (CardLayout)(cards.getLayout());

//++swapNumber;

//cardlayout.show(cards, cardText[swapNumber%2]); cardLayout.next(cards);

}else {

Command obj = (Command)e.getSource(); obj.execute();

}

}

The testStrategy(TestStrategy strategy, String m) method allows the application to send in the appropriate Strategy algorithm class along with a String variable that will be applied to that algorithm. The object reference, called strategy, invokes the test() method in the TestStrategy interface:

public boolean testStrategy(TestStrategy strategyApproach, String s) { return strategyApproach.test(s);

}

The JButtonStrategy1 class invokes the execute() method when the user clicks the Strategy #1 button on the GUI panel. The text specified in the text field is stripped into individual tokens that are passed into the StartsWithAEIOU strategy class to return a boolean value, true or false, if the token starts with either an a, e, i, o, or u. Strings that satisfy this test are converted to Pig-Latin by appending the word way to the end of the string. Tokens that don’t match that test have their initial consonant value stripped from the start of the word and appended to the end along with the letters ay:

class JButtonStrategy1 extends JButton implements Command {

public JButtonStrategy1(String caption) { super(caption); } public void execute() {

String s = textfield1.getText(); String[] sArray = s.split(“[ ,]+”); StringBuffer sb = new StringBuffer();

194

Developing Effective User Interfaces with JFC

sb.append(“PIG-LATIN: “);

for (int i=0; i < sArray.length; i++) {

if (testStrategy(new StartsWithAEIOU(), sArray[i])) { sb.append(sArray[i] + “way “);

} else {

sb.append(sArray[i].replaceAll(“^([^aeiouAEIOU])(.+)”, “$2$1ay “));

}

}

messageText.setText(sb.toString());

}

}

The JButtonStrategy2 class invokes the execute() method when the user clicks the Strategy #2 button on the GUI panel. The text specified in the text field is stripped into individual tokens that are passed into the AlphabeticChars strategy class to determine if they can be properly converted to uppercase lettering:

class JButtonStrategy2 extends JButton implements Command {

public JButtonStrategy2(String caption) { super(caption); } public void execute() {

String s = textfield2.getText(); String[] sArray = s.split(“[ ,]+”); StringBuffer sb = new StringBuffer(); sb.append(“UPPERCASE: “);

for (int i=0; i < sArray.length; i++) {

if (testStrategy(new convertUppercase(), sArray[i])) { sb.append(sArray[i].toUpperCase());

sb.append(“ “);

}

}

messageText.setText(sb.toString());

}

}

class JButtonClear extends JButton implements Command {

public JButtonClear(String caption) { super(caption); } public void execute() {

textfield1.setText(“”);

textfield2.setText(“”); messageText.setText(“User cleared text: “);

}

}

public void itemStateChanged(ItemEvent evt) { CardLayout cl = (CardLayout)(cards.getLayout()); cl.show(cards, (String)evt.getItem());

}

public interface Command { public void execute();

}

195

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]