Public class FlowLayout extends Object

implements LayoutManager, Serializable { }

В следующем примере демонстрируются возможности поточной компоновки различных элементов управления.

/* пример # 1 : поточная компоновка по центру: FlowLayoutEx.java */

package chapt13;

importjava.awt.*;

importjavax.swing.*;

public class FlowLayoutEx extends JApplet {

private Component c[] = new Component[9];

 

public void init() {

String[] msg =

{ "Метка 1", "Метка 2", "Метка 3" };

String[] str =

{ "Кнопка 1", "Кнопка 2", "Кнопка 3" };

String[] txt = {"Текст 1", "Текст 2", "Текст 3"};

//установка менеджера размещений

setLayout(new FlowLayout());

setBackground(Color.gray);

setForeground(Color.getHSBColor(1f, 1f, 1f));

for (int i = 0; i < c.length/3; i++) {

c[i] = new JButton(str[i]);

add(c[i]);

c[i + 3] = new JLabel(msg[i]);

add(c[i + 3]);

c[i+6] = new JTextField(txt[i]);

add(c[i + 6]);

}

setSize(450, 150);

}

}

Перегружаемый метод add(Component ob), определенный в классе java.awt.Container (подклассе Component), добавляет компоненты JButton, JLabel, JTextField к окну и прорисовывает их всякий раз, когда окно отображается на экран.

Метод setLayout(LayoutManager mgr) устанавливает менеджер размещения для данного контейнера. Результаты работы апплета приведены на рисунке.

Рис. 13.1.Размещение компонентов FlowLayout

Менеджер GridLayout разделяет форму на заданное количество рядов и колонок. В отличие от него компоновка BoxLayout размещает некоторое количество компонентов по вертикали или горизонтали. На способ расположения компонентов изменение размеров формы не влияет.

/* пример # 2 : компоновка в табличном виде: GridLayoutEx.java */

package chapt13;

import javax.swing.*;

import java.awt.*;

public class GridLayoutEx extends JApplet {

private Component b[] = new Component[7];

public void init() {

setLayout(new GridLayout(2, 4));/*две строки,

четыре столбца*/

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

add((b[i] = new JButton("(" + i + ")")));

}

}

Рис. 13.2. Размещение компонентов GridLayout

Менеджер BorderLayout позволяет позиционировать элементы и группы из них в областях фиксированного размера, граничащих со сторонами фрейма, которые обозначаются параметрами сторонами света: NORTH, SOUTH, EAST, WEST. Остальное пространство обозначается как CENTER.

/* пример # 3 : фиксированная компоновка по областям:

BorderGridLayoutDemo.java */

package chapt13;

import java.awt.BorderLayout;

import java.awt.GridLayout;

import java.awt.Container;

import javax.swing.JPanel;

import javax.swing.JFrame;

import javax.swing.JButton;

import javax.swing.JToggleButton;// «западающая» кнопка

 

public class BorderGridLayoutDemo extends JFrame {

 

public BorderGridLayoutDemo() {

Container c = getContentPane();

c.setLayout(new BorderLayout());

c.add(new JToggleButton("--1--"), BorderLayout.WEST);

c.add(new JToggleButton("--2--"), BorderLayout.SOUTH);

c.add(new JToggleButton("--3--"), BorderLayout.EAST);

JPanel jPanel = new JPanel();

c.add(jPanel, BorderLayout.NORTH);

jPanel.setSize(164, 40);

jPanel.setLayout(new GridLayout(2, 4));

for (int i = 0; i < 7; i++)

jPanel.add(new JButton("" + i));

}

public static void main(String[] args) {

BorderGridLayoutDemo fr =

new BorderGridLayoutDemo();

fr.setSize(300, 200);

fr.setTitle("Border & Grid Layouts Example");

fr.setDefaultCloseOperation(EXIT_ON_CLOSE);

fr.setVisible(true);

}

}

Рис. 13.3. Размещение компонентов BorderLayoutиGridLayout

Компоновка BoxLayout позволяет группировать элементы в подобластях фрейма в строки и столбцы. Возможности класса Boxпозволяют размещать компоненты в рамке, ориентированной горизонтально или вертикально.

/* пример # 4 : компоновка в группах с ориентацией: BoxLayoutDemo.java */

package chapt13;

import java.awt.BorderLayout;

import java.awt.Container;

import java.awt.Font;

import javax.swing.Box;

import javax.swing.BoxLayout;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JToggleButton;

import javax.swing.border.EtchedBorder;

import javax.swing.border.TitledBorder;

 

public class BoxLayoutDemo extends JFrame {

 

public BoxLayoutDemo() {

Container c = getContentPane();

setBounds(20, 80, 300, 300);

c.setLayout(new BorderLayout());

Box row = Box.createHorizontalBox();

for (int i = 0; i < 4; i++) {

JButton btn = new JButton("Кн " + i);

btn.setFont(new Font("Tahoma", 1, 10 + i * 2));

row.add(btn);

}

c.add(row, BorderLayout.SOUTH);

 

JPanel col = new JPanel();

col.setLayout(

new BoxLayout(col, BoxLayout.Y_AXIS));

col.setBorder(

new TitledBorder(new EtchedBorder(), "Столбец"));

for (int i = 0; i < 4; i++) {

JToggleButton btn =

new JToggleButton("Кнопка " + i);

col.add(btn);

}

c.add(col, BorderLayout.WEST);

}

public static void main(String[] args) {

BoxLayoutDemo frame = new BoxLayoutDemo();

frame.setDefaultCloseOperation(EXIT_ON_CLOSE);

frame.setVisible(true);

}

}

Рис. 13.4. Размещение компонентов BoxLayoutиBox

Для того чтобы располагать компоненты в произвольных областях фрейма, следует установить для менеджера размещений значение null и воспользоваться методом setBounds().

/* пример # 5 : произвольное размещение: NullLayoutEx.java */

package chapt13;

import java.awt.Container;

import javax.swing.*;

 

public class NullLayoutEx extends JFrame {

public NullLayoutEx() {

Container c = getContentPane();

//указание размеров фрейма

setBounds(20, 80, 300, 300);

c.setLayout(null);

JButton jb = new JButton("Кнопка");

//указание координат и размеров кнопки

jb.setBounds(200, 50, 90, 40);

c.add(jb);

JTextArea jta = new JTextArea();

//указание координат и размеров текстовой области

jta.setBounds(10, 130, 180, 70);

jta.setText("Здесь можно вводить текст");

c.add(jta);

}

public static void main(String args[]) {

NullLayoutEx nl = new NullLayoutEx();

nl.setDefaultCloseOperation(EXIT_ON_CLOSE);

nl.setVisible(true);

}

}

Рис. 13.5. Произвольное размещение компонентов

Элементы управления

Все элементы управления из пакета AWT являются наследниками классов Componentи Container. При использовании пакета Swing компоненты наследуются от класса JComponent, производного от класса Container.

В качестве примеров можно привести текстовые метки Label, JLabel, которые создаются с помощью конструкторов, устанавливающих текст метки.
Возможность изменения текста метки предоставляет метод
setText(String txt). Получить значение текста метки можно методом getText().

Кнопки Button и JButton, CheckBox и JCheckBox, RadioButton и JRadioButton, JToggleButton используются для генерации и обработки событий.

Списки Listи JList позволяют выбирать один или несколько элементов из списка.­

Полосы прокрутки ScrollBar и JScrollBar используются для облегчения просмотра.

Однострочная область ввода TextField и JTextField и многострочная область ввода – TextArea и JTextArea позволяют редактировать и вводить текст (см. рис. 13.6).

Суперклассом кнопок является класс AbstractButton, от которого наследуются два наиболее используемых класса: JButton и JToggleButton. Первый предназначен для создания обычных кнопок, а второй - для создания «залипающих» кнопок, радиокнопок (класс JRadioButton) и отмечаемых кнопок (класс JCheckBox). Кроме указанных, от AbstractButton наследуется два класса JCheckBoxMenuItem и JRadioButtonMenuItem, применяемых для организации меню с радиокнопками и отмечаемыми кнопками (см. рис. 13.7).

Рис. 13.6.Иерархия наследования компонентов в библиотеке Swing

Рис. 13.7.Классы кнопок в Swing

Процесс создания кнопок достаточно прост: вызывается конструктор JButton с меткой, которую нужно поместить на кнопке. Класс JButton библиотеки Swing для создания обычных кнопок предлагает несколько различных конструкторов: JButton(),JButton(String s), JButton(Icon i),JButton(String s, Icon i).

Если используется конструктор без параметров, то получится абсолютно пустая кнопка. Задав текстовую строку, получим кнопку с надписью. Для создания кнопки с рисунком конструктору передается ссылка на класс пиктограммы. Класс JButton содержит несколько десятков методов. JButton - это компонент, который автоматически перерисовывается как часть обновления. Это означает, что не нужно явно вызывать перерисовку кнопки, как и любого управляющего элемента; он просто помещается на форму и сам автоматически заботится о своей перерисовке. Чтобы поместить кнопку на форму, достаточно выполнить это в методе init(). Каждый раз, когда кнопка нажимается, гене­рируется action-событие. Оно посылается блокам прослушивания, зарегистрированным для приема события от этого компонента.

// пример # 6 : кнопка и ее методы: VisualEx.java

package chapt13;

import javax.swing.JPanel;

import javax.swing.JApplet;

import javax.swing.JButton;

import javax.swing.JLabel;

import javax.swing.JTextField;

import java.awt.FlowLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

 

public class VisualEx extends JApplet {

private JPanel jContentPane = null;

private JButton yesBtn = null;

private JButton noBtn = null;

private JLabel label = null;

private JTextField textField = null;

 

public void init() {

setSize(180, 160);

setContentPane(getJContentPane());

setBackground(java.awt.Color.white);

}

private JPanel getJContentPane() {

if (jContentPane == null) {

label = new JLabel();

label.setText("");

jContentPane = new JPanel();

jContentPane.setLayout(new FlowLayout());

jContentPane.add(getYesBtn(), null);

jContentPane.add(getNoBtn(), null);

jContentPane.add(label, null);

jContentPane.add(getTextField(), null);

}

return jContentPane;

}

private JButton getYesBtn() {

if (yesBtn == null) {

yesBtn = new JButton();

yesBtn.setText("казнить");

yesBtn.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

label.setText("Казнить,");

textField.setText("нельзя помиловать");

}

});

}

return yesBtn;

}

private JButton getNoBtn() {

if (noBtn == null) {

noBtn = new JButton();

noBtn.setText("помиловать");

noBtn.addActionListener(new ActionListener() {

 

public void actionPerformed(ActionEvent e) {

label.setText("Казнить нельзя,");

textField.setText("помиловать");

}

});

}

return noBtn;

}

private JTextField getTextField() {

if (textField == null) {

textField = new JTextField();

textField.setColumns(12);

textField.setHorizontalAlignment(JTextField.CENTER);

textField.setEditable(false);

}

return textField;

}

}

Рис. 13.8. Апплет с кнопками, меткой и текстовым полем

МетодgetSource() возвращает ссылку на объект, явившийся источником события, который преобразуется в объект JButton. Метод getText()в виде строки извлекает текст, который изображен на кнопке, и помещает его с помощью метода setText() объекта JLabel в объект lbl. При этом определяется, какая из кнопок была нажата.

Для отображения результата нажатия кнопки использован компонент JTextField, представляющий собой поле, где может быть размещен и изменен текст. Хотя есть несколько способов создания JTextField, самым простым является сообщение конструктору нужной ширины текстового поля. Как только JTextField помещается на форму, можно изменять содержимое, используя метод setText(). Реализацию действий, ассоциированных с нажатием кнопки, лучше производить в потоке во избежание “зависания”

Класс JComboBox применяется для создания раскрывающегося списка альтернативных вариантов, из которых пользователем производится выбор. Таким образом, данный элемент управления имеет форму меню. В неактивном состоянии компонент типа JComboBox занимает столько места, чтобы по­казывать только текущий выбранный элемент. Для определения выбранного элемента можно вызвать метод getSelectedItem() или getSelectedIndex(). Чтобы сделать элемент редактируемым, следует использовать метод setEditable(boolean editable). Существуют методы по вставке и удалению элементов списка во время выполнения программы insertItemAt(int pos) и removeItemAt(int pos).

// пример # 7 : простой выпадающий список: ComboBoxEx.java

package chapt13;

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import javax.swing.*;

 

public class ComboBoxEx extends JApplet {

private final int N = 3;

private JTextField textField = new JTextField(2);

private JComboBox comboBox = new JComboBox();

private Map<String, Integer> exams =

new HashMap<String, Integer>(N);

private class ComboListener implements ItemListener {

// реакция на изменение текущего значения ComboBox

public void itemStateChanged(ItemEvent ev) {

String name = (String) ev.getItem();

textField.setText(exams.get(name).toString());

}

}

public void init() {

exams.put("Программирование", 4);

exams.put("Алгебра", 7);

exams.put("Топология", 8);

// добавление элементов в ComboBox

Iterator i = exams.entrySet().iterator();

while (i.hasNext())

comboBox.addItem(

((Map.Entry) i.next()).getKey());

comboBox.addItemListener(new ComboListener());

textField.setText(exams.get(

comboBox.getSelectedItem()).toString());

 

Container c = getContentPane();

c.setLayout(new FlowLayout());

c.add(comboBox);

c.add(textField);

}

}

Рис. 13.9. Выпадающий список

При выборе элемента списка генерируется событие ItemEvent и посылается всем блокам прослушивания, зарегистрированным для приема уведомлений о событиях данного компонента. Каждый блок прослушивания реализует интерфейс ItemListener. Этот интерфейс определяет метод itemStateChanged(). Объект ItemEvent передается этому методу в качестве аргумента. Приведенная программа позволяет выбрать из списка число, возводит его в квадрат и выводит в объект JTextField.

В следующем примере приведен способ по организации многоязычного меню. Здесь также используются возможности класса ResourceBundle по извлечению информации из файла свойств (properties). При разработке больших приложений не рекомендуется помещать в код текстовые сообщения, так как при их изменении программисту потребуется корректировать и затем перекомпилировать большую часть приложения.

/* пример # 8 : регистрация, генерация и обработка ActionEvent:

ButtonActionDemo.java, Messages.java */

package chapt13;

import java.awt.FlowLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.ItemEvent;

import java.awt.event.ItemListener;

import java.io.UnsupportedEncodingException;

import java.util.Locale;

import javax.swing.JButton;

import javax.swing.JComboBox;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

 

public class ButtonActionDemo extends JFrame {

private static final String EN_LANGUAGE = "English";

private static final String RU_LANGUAGE = "Русский";

private JPanel jContentPane = null;

private JComboBox languageChooser = null;

private JButton yesBtn = null;

private JButton noBtn = null;

private JLabel jLabel = null;

 

public ButtonActionDemo() {

initialize();

}

// ActionListener для кнопки 'Yes'

private class YesButtonListener

implements ActionListener {

public void actionPerformed(ActionEvent event) {

jLabel.setText(getString("BUTTON_YES_MESSAGE"));

}

}

// ActionListener для кнопки 'No'

private class NoButtonListener

implements ActionListener {

public void actionPerformed(ActionEvent event) {

jLabel.setText(getString("BUTTON_NO_MESSAGE"));

}

}

// ItemListener для combobox

private class LanguageChooserItemListener

implements ItemListener {

public void itemStateChanged(ItemEvent e) {

if (((String) e.getItem()).equals(EN_LANGUAGE)) { Locale.setDefault(Locale.ENGLISH);

} else {

Locale.setDefault(new Locale("RU"));

}

yesBtn.setText(getString("BUTTON_YES"));

noBtn.setText(getString("BUTTON_NO"));

}

}

private void initialize() {

setSize(230, 200);

setContentPane(getJContentPane());

setTitle("JFrame");

setVisible(true);

}

private JPanel getJContentPane() {

if (jContentPane == null) {

jLabel = new JLabel();

jLabel.setText("JLabel");

jContentPane = new JPanel();

jContentPane.setLayout(new FlowLayout());

}

languageChooser = new JComboBox();

languageChooser.addItem(EN_LANGUAGE);

languageChooser.addItem(RU_LANGUAGE);

languageChooser.addItemListener(

new LanguageChooserItemListener());

 

yesBtn = new JButton(getString("BUTTON_YES"));

yesBtn.addActionListener(

new YesButtonListener());

 

noBtn = new JButton(getString("BUTTON_NO"));

noBtn.addActionListener(

new NoButtonListener());

 

jContentPane.add(languageChooser);

jContentPane.add(yesBtn);

jContentPane.add(noBtn);

jContentPane.add(jLabel);

 

return jContentPane;

}

public static void main(String[] args) {

Locale.setDefault(Locale.ENGLISH);

ButtonActionDemo ob = new ButtonActionDemo();

ob.setDefaultCloseOperation(EXIT_ON_CLOSE);

}

private String getString(String property) {

String text = "";

try {

text = new String(

Messages.getString(property).getBytes(

"ISO-8859-1"), "CP1251");

} catch (UnsupportedEncodingException ex) {

ex.printStackTrace();

}

return text;

}

}

package chapt13;

import java.util.MissingResourceException;

import java.util.ResourceBundle;

public class Messages {

private static final String BUNDLE_NAME =

"chapt13.messages";

private static final ResourceBundle RESOURCE_BUNDLE =

ResourceBundle.getBundle(BUNDLE_NAME);

 

public static String getString(String key) {

try {

return RESOURCE_BUNDLE.getString(key);

} catch(MissingResourceException e) {

return '!' + key + '!';

}

}

}

Файлы ресурсов messages.propertiesи messages_ru.properties, из которых извлекаются сообщения на английском и русском языках соответственно, выглядят следующим образом:

BUTTON_YES=yes

BUTTON_NO=no

BUTTON_YES_MESSAGE=Button <yes> is pressed

BUTTON_NO_MESSAGE=Button <no> is pressed

BUTTON_YES=да

BUTTON_NO=нет

BUTTON_YES_MESSAGE=Нажата кнопка <да>

BUTTON_NO_MESSAGE=Нажата кнопка <нет>

Рис. 13.10.Результат нажатия кнопки «да» отображен в метке

Команда, ассоциированная с кнопкой, возвращается вызовом метода getActionCommand() класса ActionEvent, экземпляр которого содержит всю информацию о событии и его источнике.

В следующем примере рассмотрен вариант объединения нескольких радио­кнопок (JRadioButton) в группу и отслеживание изменения их состояния.

/* пример # 9 : отслеживание изменения состояния флажка:

RadioBtnGroupEx.java */

package chapt13;

import java.awt.*;

import java.awt.event.ItemEvent;

import java.awt.event.ItemListener;

import javax.swing.*;

public class RadioBtnGroupEx extends JApplet {

private ButtonGroup btnGroup = new ButtonGroup();

private JLabel label = null;

private class RadioItemListener

implements ItemListener {

public void itemStateChanged(ItemEvent e) {

boolean selected =

(e.getStateChange() == ItemEvent.SELECTED);

AbstractButton button =

(AbstractButton) e.getItemSelectable();

if (selected)

label.setText("Selected Button: "

+ button.getActionCommand());

System.out.println(

"ITEM Choice Selected: " + selected +

", Selection: " + button.getActionCommand());

}

}

public void init() {

Container c = getContentPane();

c.setLayout(new FlowLayout());

 

JRadioButton red = new JRadioButton("Red");

red.setSelected(true);

btnGroup.add(red);

c.add(red);

label = new JLabel("Selected Button: Red");

JRadioButton green = new JRadioButton("Green");

btnGroup.add(green);

c.add(green);

JRadioButton blue = new JRadioButton("Blue");

btnGroup.add(blue);

c.add(blue);

ItemListener itemListener = new RadioItemListener();

red.addItemListener(itemListener);

green.addItemListener(itemListener);

blue.addItemListener(itemListener);

 

c.add(label);

}

}

Рис. 13.11. Элемент управления JRadioButton

Ниже приведен простейший вариант использования объекта класса JSlider, представляющий собой ползунковый регулятор, позволяющий выбрать значение из интервала возможных значений.

/* пример # 10 : использование ползункового регулятора: SliderEx.java */

package chapt13;

import java.awt.*;

import javax.swing.*;

import javax.swing.event.ChangeEvent;

import javax.swing.event.ChangeListener;

 

public class SliderEx extends JApplet {

private JLabel sliderValue =

new JLabel("Slider Value: 25");

 

private class SliderListener

implements ChangeListener {

public void stateChanged(ChangeEvent e) {

sliderValue.setText("Slider Value: " +

((JSlider) (e.getSource())).getValue());

}

}

public void init() {

Container c = getContentPane();

c.setLayout(new FlowLayout());

 

JSlider slider =

new JSlider(JSlider.HORIZONTAL, 0, 50, 25);

// установка видимости меток и делений

slider.setPaintLabels(true);

slider.setPaintTicks(true);

// установка расстояний между делениями

slider.setMinorTickSpacing(2);

slider.setMajorTickSpacing(10);

slider.setLabelTable(

slider.createStandardLabels(10));

slider.addChangeListener(new SliderListener());

c.add(slider);

c.add(sliderValue);

}

}

Рис. 13.12. Элемент управления JSlider

Блок прослушивания событий в ответ на генерацию объекта события ItemEvent вызвал метод itemStateChange(ItemEvent e), извлекающий из объекта класса ItemEvent константу состояния, в данном случае SELECTED, а в ответ на генерацию объекта события ChangeEvent вызывается метод stateChanged(ChangeEvent e).

Для добавления в приложение различного вида всплывающих меню и диалоговых окон следует использовать обширные возможности класса JOptionPane. Эти возможности реализуются статическими методами класса вида showИмяDialog(параметры). Наиболее используемыми являются методы showConfirmDialog(), showMessageDialog(), showInputDialog()
и showOptionDialog().

Для подтверждения/отказа выполняемого в родительском окне действия применяется метод showConfirmDialog().

/* пример # 11 : диалог Да/Нет: DemoConfirm.java */

packagechapt13;

import javax.swing.*;

 

public class DemoConfirm {

public static void main(String[] args) {

int result = JOptionPane.showConfirmDialog(

null,

"Хотите продолжить?",

"Сhooser",

JOptionPane.YES_NO_OPTION);

if (result == 0)

System.out.println("You chose Yes");

Else

System.out.println("You chose No");

}

}

В качестве первого параметра метода указывается окно, к которому относится сообщение, но так как в данном случае здесь и далее используется консоль, то он равен null.

Рис. 13.13. Диалог выбора

Для получения вариаций указанного диалога можно использовать следующие константы: YES_NO_CANCEL_OPTION, OK_CANCEL_OPTION, DEFAULT_OPTION и некоторые другие.

Для показа сообщений (информационных, предупреждающих, вопросительных и т.д.) применяется метод showMessageDialog().

/* пример # 12 : сообщение: DemoMessage.java */

packagechapt13;

import javax.swing.*;

 

public class DemoMessage {

public static void main(String[] args) {

JOptionPane.showMessageDialog(

null,

"Файл может быть удален!",

"Внимание!",

JOptionPane.WARNING_MESSAGE);

// ERROR_MESSAGE – сообщение об ошибке

// INFORMATION_MESSAGE - информационное сообщение

// WARNING_MESSAGE - уведомление

// QUESTION_MESSAGE - вопрос

// PLAIN_MESSAGE - без иконки

}

}

Рис. 13.14.Вывод сообщения

Если необходимо обязать пользователя приложения ввести какую-либо ин­формацию на определенном этапе работы, то следует использовать возможности метода showInputDialog(). Причем простейший запрос создать очень легко.

/* пример # 13 : запрос на ввод: DemoInput.java */

packagechapt13;

import javax.swing.*;

 

public class DemoInput {

public static void main(String[] args) {

String str =

JOptionPane.showInputDialog(

"Please input a value");

if (str != null)

System.out.println("You input : " + str);

}

}

Рис. 13.15. Простейший запрос на ввод строки

Следующий пример предоставляет возможность выбора из заранее определенного списка значений.

/* пример # 14 : формирование запроса на выбор из списка:

DemoInputWithOptions.java */

packagechapt13;

import javax.swing.*;

 

public class DemoInputWithOptions {

public static void main(String[] args) {

Object[] possibleValues =

{ "легкий", "средний", "трудный" };

Object selectedValue =

JOptionPane.showInputDialog(

null,

"Выберите уровень",

"Input",

JOptionPane.INFORMATION_MESSAGE,

null,

possibleValues,

possibleValues[0]);

// possibleValues[1] - элемент для фокуса

// второй null – иконка по умолчанию

if (selectedValue != null)

System.out.println("You input : "

+ selectedValue);

}

}

Рис. 13.16. Запрос на выбор из списка

Другим способом создания диалога с пользователем является применение возможностей класса JDailog. В этом случае можно создавать диалоги с произвольным набором компонентов.

// пример # 15 : произвольный диалог: MyDialog.java

packagechapt13;

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

 

class MyDialog extends JDialog{

private final JFrame parent;

private JCheckBox cb = new JCheckBox();

private JButton ok = new JButton("Ok");

public MyDialog(final JFrame parent, String name) {

super(parent, name, true);

this.parent = parent;

 

Container c = getContentPane();

c.setLayout(new FlowLayout());

c.add(new JLabel("Exit ?"));

ok.addActionListener(

new ActionListener(){

public void actionPerformed(

ActionEvent e) {

dispose();

if (cb.isSelected())

parent.dispose();

}

});

c.add(cb);

c.add(ok);

 

setSize(200, 100);

setDefaultCloseOperation(EXIT_ON_CLOSE);

setVisible(true);

}

}

public class DemoJDialog extends JFrame {

private JButton jButton = new JButton("Dialog");

 

DemoJDialog() {

super("My DialogFrame");

Container c = getContentPane();

c.setLayout(new FlowLayout());

jButton.addActionListener(

new ActionListener() {

public void actionPerformed(

ActionEvent e) {

JDialog jDialog =

new MyDialog(DemoJDialog.this, "MyDialog");

}

});

c.add(jButton);

}

 

public static void main(String[] args) {

DemoJDialog f = new DemoJDialog();

f.setDefaultCloseOperation(EXIT_ON_CLOSE);

f.setSize(200, 120);

f.setVisible(true);

}

}

Рис. 13.17. Произвольный диалог

Для создания пользовательского меню следует воспользоваться возможностями классов JMenu, JMenuBar и JMenuItem.

/* пример # 16 : создание меню: SimpleMenu.java */

packagechapt13;

import javax.swing.*;

import java.awt.event.*;

 

public class SimpleMenu extends JApplet {

private JMenu menu;

private JMenuItem item1, item2;

 

private class MenuItemListener

implements ActionListener {

public void actionPerformed(ActionEvent e) { JMenuItem jmi =

(JMenuItem) e.getSource();

if (jmi.equals(item2))

System.exit(0);

Else

showStatus("My Simple Menu");

}

}

public void init() {

JMenuBar menubar = new JMenuBar();

setJMenuBar(menubar);

menu = new JMenu("Main");

 

item1 = new JMenuItem("About");

item2 = new JMenuItem("Exit");

item1.addActionListener(

new MenuItemListener());

item2.addActionListener(

new MenuItemListener());

 

menu.add(item1);

menu.add(item2);

menubar.add(menu);

}

}

Рис. 13.18. Простейшее меню

Класс JTextArea позволяет вводить и отображать многострочную информацию. Такая возможность полезна при обработке текстов, двумерных массивов. Пользователь может сам вводить в этот объект информацию, разделяя строки нажатием клавиши <Enter>. Этот объект не имеет полосы прокрутки (ее можно добавить), поэтому если введено строк больше, чем объявлено, но лишний текст будет утрачен. Класс JTextArea является подклассом JTextComponent, следовательно, программисту доступны все его возможности. В частности, есть возможность обработки части текста, выделенной пользователем, а также определение количества строк и столбцов (см. рис. 13.19).

JTextComponent
JEditorPane
JTextArea
JTextField
JTextPane
JPasswordField
JFormattedTextField

В примере решается простая задачи загрузки из файла в объектJTextArea двумерного массива и его примитивная обработка. При загрузке матрицы из файла для поиска соответствующего дискового файла использованы возможности класса JFileChooser.

Рис. 13.19.Классы текстовых компонентов

/* пример # 17 : вывод двумерного массива в текстовое поле: ArraysWork.java */

package chapt13;

import java.awt.*;

import java.awt.event.*;

import java.io.*;

import java.util.*;

import javax.swing.*;

import javax.swing.text.BadLocationException;

import javax.swing.plaf.metal.MetalBorders.TextFieldBorder;

 

public class ArraysWork extends JFrame {

private JFileChooser fileChooser =

new JFileChooser("D:\\");

private JButton openBtn = new JButton("Open");

private JButton resultBtn = new JButton("Result");

private JButton clearBtn = new JButton("Clear");

private JTextArea textArea = new JTextArea();

private ArrayList<int[]> arrays =

new ArrayList<int[]>();

 

private ArraysWork() {

Container contentPane = getContentPane();

contentPane.setLayout(null);

JPanel col = new JPanel();

col.setBounds(10, 10, 90, 110);

col.setLayout(new GridLayout(3, 1, 0, 8));

openBtn.addActionListener(

new ButtonListener());

resultBtn.addActionListener(

new ButtonListener());

clearBtn.addActionListener(

new ButtonListener());

col.add(openBtn);

col.add(resultBtn);

col.add(clearBtn);

contentPane.add(col, BorderLayout.EAST);

textArea.setBounds(130, 10, 110, 110);

textArea.setBorder(new TextFieldBorder());

textArea.setFont(

new Font("Courier New", Font.PLAIN, 12));

contentPane.add(textArea);

}

private class ButtonListener

implements ActionListener {

public void actionPerformed(ActionEvent event) {

if (event.getSource() == clearBtn)

textArea.setText("");

else if (event.getSource() == resultBtn)

viewArrays(true);

else if (event.getSource() == openBtn)

readArraysFromFile();

}

}

public static void main(String[] args) {

ArraysWork frame = new ArraysWork();

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setBounds(200, 100, 280, 155);

frame.setVisible(true);

}

 

private void readArraysFromTextArea() {

arrays.clear();

// обработка строк текстового поля

for (int i = 0; i < textArea.getLineCount(); i++)

try {

int startOffset = textArea.getLineStartOffset(i);

int endOffset = textArea.getLineEndOffset(i);

StringTokenizer str =

new StringTokenizer(textArea.getText(

startOffset, endOffset - startOffset), " \n");

arrays.add(new int[str.countTokens()]);

int k = 0;

while (str.hasMoreTokens())

arrays.get(i)[k++] =

new Integer(str.nextToken()).intValue();

} catch (BadLocationException e) {

e.printStackTrace();

} catch (NumberFormatException e) {

JOptionPane.showMessageDialog(

null, "Enter only numbers!",

"Fatal error!", JOptionPane.ERROR_MESSAGE);

}

}

 

private void readArraysFromFile() {

String filePath = null;

int rVal =

fileChooser.showOpenDialog(fileChooser);

fileChooser.setVisible(true);

if (JFileChooser.APPROVE_OPTION == rVal)

filePath = fileChooser.getSelectedFile().getPath();

if (filePath == null)

return;

try {

Scanner sc = new Scanner(

new File(filePath));

int i = 0;

while (sc.hasNextLine()) {

StringTokenizer str =

new StringTokenizer(sc.nextLine());

arrays.add(new int[str.countTokens()]);

int k = 0;

while (str.hasMoreTokens())

arrays.get(i)[k++] =

new Integer(str.nextToken()).intValue();

i++;

}

} catch (FileNotFoundException e) {

e.printStackTrace();

}

viewArrays(false);

}

 

private void viewArrays(boolean result) {

if (result) {

readArraysFromTextArea();

handlingOfArrays();

}

textArea.setText("");

for (int i = 0; i < arrays.size(); i++) {

Formatter fmt = new Formatter();

for (int j = 0; j < arrays.get(i).length; j++)

fmt.format("%4d", arrays.get(i)[j]);

textArea.append(fmt.toString() + '\n');

}

}

 

void handlingOfArrays() {

for (int i = 0; i < arrays.size(); i++)

try {

arrays.get(i)[0] = -arrays.get(i)[0];

} catch (ArrayIndexOutOfBoundsException e) {

throw new AssertionError("не матрица!");

}

}

}

Рис. 13.20. Текстовое поле

Добавить полосу прокрутки можно с помощью следующего кода:

JScrollPane sp = new JScrollPane(textarea);



li>32
  • Далее ⇒