Программирование. Программирование на Java Конспект лекций (ИТМО 2010). Справочник по языку Java и может использоваться как конспект лекционного курса Системы программирования Интернетприложений
Скачать 0.85 Mb.
|
107 } } Бордюры (Border) Рисование границ вокруг компонентов (бордюров) обеспечивается с помощью интерфейса Border Border требует реализации следующих методов: // Определяет область, необходимую для рисования public Insets getBorderInsets(Component c); // Определяет прозрачность и непрозрачность границы public boolean isBorderOpaque(); // Определяет каким образом рисовать границу public void paintBorder (Component c, Graphics g, int x, int y, int width, int height) В пакет Swing входит 9 классов для рисования бордюров BevelBorder Объемный бордюр, поднятый или опущенный CompoundBorder Составной бордюр DefaultBorder Бордюр по умолчанию — реализация интерфейса EmptyBorder Пустой бордюр EtchedBorder Бордюр-канавка LineBorder Цветной бордюр произвольной толщины MatteBorder Бордюр с заполнением цветом или изображением SoftBevelBorder Объемный бордюр с закругленными углами TitledBorder Бордюр с заголовками в различных позициях Классы меню Классы, обеспечивающие работу с меню ( JCheckBoxMenuItem , JMenuItem , JRadioButtonMenuItem , JMenu , JMenuBar , JSeparator ), являются подклассами компонента JComponent . Это позволяет в отличие от AWT добавить меню в любое место программы, к любому контейнеру. public class MenuTester extends JFrame implements ActionListener { public void actionPerformed (ActionEvent e) { System.out.println (e.getActionCommand()); } 108 public MenuTester() { super ("Menu Example"); JMenuBar jmb = new JMenuBar(); JMenu file = new JMenu ("File"); JMenuItem item; file.add (item = new JMenuItem ("New")); item.addActionListener (this); file.add (item = new JMenuItem ("Open")); item.addActionListener (this); file.addSeparator(); file.add (item = new JMenuItem ("Close")); item.addActionListener (this); jmb.add (file); JMenu edit = new JMenu ("Edit"); edit.add (item = new JMenuItem ("Copy")); item.addActionListener (this); edit.add (item = new JMenuItem ("Woods", tigerIcon)); item.setHorizontalTextPosition (JMenuItem.RIGHT); item.addActionListener (this); JCheckBoxMenuItem check= new JCheckBoxMenuItem ("Toggle"); check.addActionListener (this); edit.add (check);jmb.add (edit); setJMenuBar (jmb); }} Классы JFrame, JWindow, JDialog Основное отличие этих классов от других компонентов Swing заключается в том, что они не являются легковесными компонентами, и наследуются соответственно от Frame , Window , Dialog . В отличие от Frame , Window , Dialog , для добавления компонентов в JFrame , JWindow , JDialog используется панель содержимого (content pane). public class FrameTester { public static void main (String args[]) { JFrame f = new JFrame ("JFrame Example"); Container c = f.getContentPane(); c.setLayout (new FlowLayout()); for (int i = 0; i < 5; i++) { c.add(new JButton("No")).setBackground(SystemColor.control); c.add (new Button("Batter")); } c.add (new JLabel ("Swing")); f.setSize (300, 200); f.show(); 109 } Класс JPopupMenu Позволяет связать выпадающее меню с любым компонентом. public class PopupPanel extends JPanel { JPopupMenu popup = new JPopupMenu (); public PopupPanel() { JMenuItem item; popup.add (item = new JMenuItem ("Cut")); popup.add (item = new JMenuItem ("Copy")); popup.add (item = new JMenuItem ("Paste")); popup.addSeparator(); popup.add (item = new JMenuItem ("Select All")); enableEvents (AWTEvent.MOUSE_EVENT_MASK); } protected void processMouseEvent (MouseEvent e) { if (e.isPopupTrigger()) popup.show (e.getComponent(), e.getX(), e.getY()); super.processMouseEvent (e); } } Подсказки (ToolTip) В пакете swing имеется класс JtoolTip , предназначенный для реализации подсказок, однако обычно достаточно вызвать метод setToolTip() класса JComponent public class TooltipPanel extends JPanel { public TooltipPanel() { JButton myButton = new JButton("Hello"); myButton.setBackground (SystemColor.control); myButton.setToolTipText ("World"); add(myButton); } } Класс JToolBar Используется для реализации линейки инструментов. public class ToolbarPanel extends JPanel { ToolbarPanel() { setLayout (new BorderLayout()); JToolBar toolbar = new JToolBar(); 110 JButton myButton = new JButton("Hello"); toolbar.add(myButton); Icon tigerIcon = new ImageIcon("SmallTiger.gif"); myButton = new JButton(tigerIcon); toolbar.add(myButton); toolbar.addSeparator(); toolbar.add (new Checkbox ("Not")); add (toolbar, BorderLayout.NORTH); } } Класс JTabbedPane Реализует панель с закладками. public class TabbedPanel extends JPanel { String tabs[] = {"One", "Two", "Three", "Four"}; public JTabbedPane tabbedPane = new JTabbedPane(); public TabbedPanel() { setLayout(new BorderLayout()); for (int i=0;i (tabs[i])); tabbedPane.setSelectedIndex(0); add (tabbedPane, BorderLayout.CENTER); } JPanel createPane(String s) { JPanel p = new JPanel(); p.setBackground (SystemColor.control); p.add(new JLabel(s)); return p; } } Класс JSplitPane Позволяет упаковать 2 компонента с движком между ними. public class JSplitPanel extends JPanel { JComponent createSplitter (int orientation, boolean depth) { JButton butt1 = new JButton ("One"); butt1.setBackground (SystemColor.control); JComponent c; if (depth) { int newOrientation = ((orientation == JSplitPane.HORIZONTAL_SPLIT) ? newOrientation = JSplitPane.VERTICAL_SPLIT : 111 newOrientation = JSplitPane.HORIZONTAL_SPLIT); c = createSplitter (newOrientation, false); } else { c = new JButton ("Two"); c.setBackground (SystemColor.control); } JSplitPane jsp = new JSplitPane (orientation, butt1, c); return jsp; } public JSplitPanel() { // Установить компоновку только для одного компонента setLayout(new BorderLayout(10, 10)); add (createSplitter (JSplitPane.HORIZONTAL_SPLIT, false), BorderLayout.NORTH); add (createSplitter (JSplitPane.HORIZONTAL_SPLIT, false), BorderLayout.SOUTH); add (createSplitter (JSplitPane.VERTICAL_SPLIT, false), BorderLayout.WEST); add (createSplitter (JSplitPane.VERTICAL_SPLIT, false), BorderLayout.EAST); add (createSplitter (JSplitPane.VERTICAL_SPLIT, true), BorderLayout.CENTER); } } Класс BoxLayout Менеджер компоновки для размещения компонентов вдоль оси x или y. class BoxLayoutTest extends JPanel { BoxLayoutTest() { // Установить компоновку вдоль оси y setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); TextField textField = new TextField(); TextArea textArea = new TextArea(4, 20); JButton button = new JButton( "Tiger", new ImageIcon("SmallTiger.gif")); button.setBackground (SystemColor.control); add(new JLabel("TextField:")); add(textField); add(new JLabel("TextArea:")); add(textArea); add(new JLabel("Button:")); add(button); } } 112 События пакетов Swing AncestorEvent предок изменен, перемещен, удален ChangeEvent изменение состояния DocumentEvent изменение состояния документа DragEvent событие drag-and-drop ListDataEvent изменение данных списка ListSelectionEvent изменение состояния выбора списка MenuEvent событие меню TableColumnModelEven t изменение модели столбца таблицы TableModelEvent изменение модели таблицы TreeExpansionEvent свертывание и развертывание элементов дерева TreeModelEvent изменение модели дерева TreeSelectionEvent изменение выделенного элемента дерева Модели данных приложения Представляют данные, выражающиеся обычно количественно (например, значение в ячейке таблицы). Для таких моделей рекомендуется обязательное разделение логического и визуального представления. К ним относятся: Модель Компоненты ComboBoxModel JComboBox ListModel JList TableModel JTable TreeModel JTree Document JeditorPane,JTextPane,JTextArea, JTextField,JPasswordField Модели состояния GUI Определяют состояние графического компонента (кнопка нажата/не нажата). При их использовании не обязательно осуществлять раздельное управление 113 моделью, так как работа с моделями состояния GUI осуществляется неявно с помощью методов компонентов. К этим моделям относятся: Модель Компоненты ButtonModel JButton,JMenu,JMenuItem SingleSelectionModel JTabbedPane ListSelectionModel JList TableColumnModel JTable TreeSelectionModel Jtree Смешанные модели К ним относятся модели, которые частично представляют собой данные, а частично - состояние компонента. К ним относятся: Модель Компоненты ButtonModel JToggleButton,JCheckBox,JRadioButton, JCheckBoxMenuItem,JRadioButtonMenuItem BoundedRangeModel JProgressBar,JScrollBar,JSlider Модели по умолчанию Модель, связанная с компонентом, может быть определена как явным образом с помощью метода setModel() , так и автоматически. При создании компонента с ним связывается соответствующая модель по умолчанию. Например, при создании JSlider с ним связывается модель DefaultBoundedRangeModel Для более сложных объектов, таких как JTable или JTree , в пакет Swing кроме моделей по умолчанию DefaultTableModel и DefaultTreeModel входят абстрактные модели, которые реализуют часть функций, связанных с извещением об изменении данных. Абстрактные модели имеют имена, где слово Default заменено на Abstract (например AbstractTableModel ). Извещение об изменениях модели Для сообщения об изменении состояния модели используется механизм событий. Извещение об изменении состояния модели может быть осуществлено двумя способами: • Посылка легковесного извещения о том, что состояние изменилось, и требование дополнительного запроса от слушателя о том, что именно изменилось. Преимуществом данного подхода является возможность 114 использования только одного экземпляра события для всех последовательных извещений от конкретной модели. Это удобно, когда события происходят с достаточно высокой частотой. • Посылка полноопределенного извещения, где детально описывается как изменилось состояние модели. При этом для каждого события должен быть создан отдельный экземпляр события. Такой способ применяется в случаях, когда обычное извещение не может обеспечить слушателя информацией о том, что именно изменилось в модели. Легковесное извещение Модель Слушатель Событие BoundedRangeModel ChangeListener ChangeEvent ButtonModel ChangeListener ChangeEvent SingleSelectionModel ChangeListener ChangeEvent Событие ChangeEvent , содержащее источник события, посылается классу, воплощающему интерфейс ChangeListener . Этот интерфейс определяет единственный метод stateChanged(ChangeEvent e) . Для регистрации слушателя используется метод addChangeListener() . Получить источник события для последующих запросов можно с помощью метода getSource() класса ChangeEvent Полноопределенное извещение Модель Слушатель Событие ListModel ListDataListener ListDataEvent ListSelectionModel ListSelectionListener ListSelectionEven t ComboBoxModel ListDataListener ListDataEvent TreeModel TreeModelListener TreeModelEvent TreeSelectionModel TreeSelectionListener TreeSelectionEven t TableModel TableModelListener TableModelEvent TableColumnModel TableColumnModelListen er TableColumnModelE vent Document DocumentListener DocumentEvent Document UndoableEditListener UndoableEditEvent В этом случае используются специфические события и слушатели для каждой модели. Их обработка аналогична обработке событий при легковесном извещении, за исключением того, что запросы об изменении состояния делаются не у источника события, а у самого события, которое в данном случае содержит полную информацию о всех изменениях модели. 115 Деревья JTree Сложные деревья строятся реализацией интерфейса TreeModel . В простейшем случае можно поступить следующим образом: public class JTreePanel extends JPanel { JTreePanel() { setLayout(new BorderLayout()); // DefaultMutableTreeNode root = new DefaultMutableTreeNode("Contacts"); DefaultMutableTreeNode level1 = new DefaultMutableTreeNode("Business"); root.add(level1); DefaultMutableTreeNode level2 = new DefaultMutableTreeNode("JavaSoft"); level1.add(level2); level2.add(new DefaultMutableTreeNode("James Gosling")); level2.add(new DefaultMutableTreeNode("Frank Yellin")); level2.add(new DefaultMutableTreeNode("Tim Lindholm")); level2 = new DefaultMutableTreeNode("Disney"); level1.add(level2); level2.add(new DefaultMutableTreeNode("Goofy")); level2.add(new DefaultMutableTreeNode("Mickey Mouse")); level2.add(new DefaultMutableTreeNode("Donald Duck")); JTree tree = new JTree(root); JScrollPane pane = new JScrollPane(); pane.getViewport().add(tree); add(pane, BorderLayout.CENTER); } } Работа с таблицами (JTable) Пример создания таблицы с созданием собственной модели таблицы ( MyTableModel ), реализующей интерфейс TableModel в виде абстрактного класса — шаблона модели: public class SimpleTableDemo extends JPanel { public SimpleTableDemo() { JTable table = new JTable(new MyTableModel()); JScrollPane scrollPane = new JScrollPane(table); scrollPane.setPreferredSize(new Dimension(400, 100)); 116 setLayout(new GridLayout(1, 0)); add(scrollPane); } class MyTableModel extends AbstractTableModel { // данные final String[] columnNames = {"First Name", "Last Name", "Sport", "Est. Years Experience"}; final String[][] data = { {"Mary", "Campione", "Snowboarding", "5"}, {"Alison", "Huml", "Rowing", "3"}, {"Kathy", "Walrath", "Chasing toddlers", "2"}, {"Mark", "Andrews", "Speed reading", "20"}, {"Angela", "Lih", "Teaching high school", "4"} }; // реализация TableModel — размеры таблицы public int getColumnCount() {return columnNames.length;} public int getRowCount() {return data.length;} public String getColumnName(int col) {return columnNames[col];} // реализация TableModel — данные в ячейке public Object getValueAt(int row, int col) {return data[row][col];} } } 117 Обобщенное программирование Обобщенное программирование (generic programming) – описание данных и алгоритмов в программе, которое можно применить к различным типам данных, не меняя при этом само описание. Для такого описания используются специальные синтаксические конструкции, называемые шаблонами (дженериками). Шаблоны (generics) Шаблоны – описание класса, метода, атрибута без использования конкретного типа данных. Без шаблонов С шаблонами Объявление: List l = new LinkedList(); l.add(new Integer(0)); //потенциальна ошибка (*) l.add(new Double(1.1)); Использование: for(…) { Integer x = (Integer) l.iterator().next(); } Объявление: List new LinkedList l.add(new Integer(0)); //ошибка компиляции l.add(new Double(1.1); Использование: for (…) { Integer x =l.iterator().next(); } Шаблоны повышают наглядность кода и снижают количество явных преобразований типа и возможных ошибок от неявных преобразований. В примере с шаблонами отсутствует явное приведение к типу Integer . Это исключает появление ошибки ClassCastException в момент работы программы (* - при ошибочном добавлении в List элемента Double ), а также упрощает визуальное восприятие доступа к элементам и делает проще замену типа данных Integer на, например, Double Синтаксические конструкции с использованием шаблонов запрещены в перечислениях, исключительных ситуациях и анонимных встроенных классах. 118 При компиляции программы происходит уничтожение информации о шаблонах (type erasure) и приведение всех обобщенных и параметризованных типов, формальных параметров типа к использованию только базового типа. Пример: System.out.println("ArrayList +new ArrayList System.out.println("ArrayList +new ArrayList Выдаст: ArrayList ArrayList Основное применение шаблонов — коллекции. Описание типов с шаблонами (generic type) Обобщенный тип – это описание класса с использованием формальных параметров типа. Параметризованный тип — реализация обобщенного типа с использованием конкретного типа данных в качестве аргумента. описание класса без шаблонов описание с использованием шаблонов class Game { int result; int getResult(); void setResult(int result); } class Game T result; T getResult(); void setResult(T result); } Game - обобщенный тип Т – формальный параметр типа Game - параметризованный тип для представления результатов игры, например, в футбол ("2:0"), а Game в тетрис. 119 Описание методов с шаблонами (generic methods) Метод с использованием формального описания типа называется шаблонным методом. Признаком того, что метод является шаблонным служит указание типа данных с которым работат метод. В нашем примере это символ Объявление: public static return new HashSet } Вызов: // конкретный тип для подстановки выбирает компилятор по // аргументам вызова метода или оператору присвоения Set // указан явно Set Формальные параметры типа (type parameter) Формальный параметр типа — это параметр, вместо которого при создании по шаблону параметризованного типа необходимо подставить конкретный тип данных. interface Comparable } в приведенном примере E является формальным параметром типа. Формальных параметров может быть несколько — KeyValue Формальные параметры могут быть ограниченными. Ограниченный формальный параметр позволят задать возможные границы подстановки конкретных типов данных для получения параметризованного типа Ограничение могут быть с верхней и с нижней стороны дерева наследования: |