Java Applet | ||||||||||||||||||||||
JApplet | ||||||||||||||||||||||
Апплеты строятся с использованием рабочего пространства приложения. Вы наследуете от класса JApplet и перегружаете соответствующие методы. Есть несколько методов, которые управляют созданием и выполнением апплета на Web странице:
| ||||||||||||||||||||||
Внедрение на страницу | ||||||||||||||||||||||
<html> <head><title>Applet1</title></head> <hr> <OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" width="100" height="50" align= "baseline"codebase="http://java.sun.com/products/plugin/1.2.2/jinstall-1_2_2-win.cab#Version=1,2,2,0"> <PARAM NAME="code" VALUE="Applet1.class"> <PARAM NAME="codebase" VALUE="."> <PARAM NAME= "type"VALUE="application/x-java-applet;version=1.2.2"> <COMMENT> <EMBED type= "application/x-java-applet;version=1.2.2" width="200" height="200" align="baseline" code="Applet1.class" codebase="." pluginspage="http://java.sun.com/products/plugin/1.2/plugin-install.html"> <NOEMBED> </COMMENT> No Java 2 support for APPLET!! </NOEMBED> </EMBED> </OBJECT> <hr> </body> </html> | ||||||||||||||||||||||
Как устранить мерцание | ||||||||||||||||||||||
<html> <body> <hr> <applet code=ScrNoFlick.class name=ScrNoFlick width=320 height=40 > <param name=Text value="Scrolling String"> </applet> <hr> </body> </html> Приглядевшись внимательно к бегущей строке, которая рисуется в приложении SimpleScroll, вы можете заметить, что изображение строки мерцает. Мерцание может быть весьма неприятным, поэтому постараемся от него избавиться. В чем причина мерцания изображения в окне аплета? Каждый раз метод paint, ответственный за рисование, стирает содержимое окна, заполняя его фон заданным цветом. Процесс перерисовывания окна аплета, включающий в себя процедуру стирания фона окна аплета, занимает больше времени, чем период развертки изображения по вертикали на экране монитора. Поэтому изображение появляется в окне в несколько приемов, что и приводит к мерцанию. В ряде случаев можно избавиться от мерцания, изменив технику анимации. Вместо того чтобы периодически вызывать метод repaint, вы можете рисовать в потоке, т. е. в методе run. Единственное, что вы должны при этом сделать, - это получить перед запуском контекст отображения окна аплета и передать его потоку. Так как в этом случае метод paint не вызывается, окно аплета не стирается и мерцание полностью отсутствует. Однако у данного метода есть один недостаток: каждый раз при перерисовке окна, скажем при изменении его размеров или в результате перекрытия окна аплета, изображение в окне будет стираться. Чтобы этого избежать, следует предусмотреть возможность восстановления внешнего вида окна внутри метода paint в том виде, в котором оно находилось до перерисовки, а это не всегда просто. Более интересен и практичен метод двойной буферизации. Его идея заключается в том, что изображение рисуется не в окне аплета, а готовится в оперативной памяти и затем, уже готовое, выводится в окно. Так как процесс подготовки не виден пользователю, то не видно и мерцания. Для исключения стирания содержимого окна аплета в процессе перерисовки нужно переопределить метод update. Дело в том, что реализация update, используемая по умолчанию, стирает окно перед вызовом paint. Для исключения мерцания в процессе анимации мы должны подготовить свой вариант этого метода, не стирающий окно. В аплете ScrNoFlick, который функционально полностью аналогичен аплету SimpleScroll, мы применили описанный выше способ устранения мерцания окна, предусмотрев буферизацию вывода и переопределение метода update листинг. import java.applet.*; import java.awt.*; public class ScrNoFlick extends Applet implements Runnable { private Thread m_ScrNoFlick = null; private String m_Text = "Scrolling String"; private final String PARAM_Text = "Text"; int m_StringSize; int m_CurrentXPosition; private Image m_MemImage; private Graphics m_MemImage_Graphics; Dimension m_MemImageDim = null; public String getAppletInfo() { return "Name: ScrNoFlick\r\n" + "Author: Alexandr Frolov\r\n" + "E-mail: frolov@glas.apc.org\r\n" + "Web: http://www.glasnet.ru/~frolov," + " http://www.dials.ccas.ru/frolov"; } public String[][] getParameterInfo() { String[][] info = { { PARAM_Text, "String", "Scrolling String" }, }; return info; } public void init() { String param; param = getParameter(PARAM_Text); if (param != null) m_Text = param; FontMetrics fm = getFontMetrics(getFont()); m_StringSize = fm.stringWidth(m_Text); m_CurrentXPosition = size().width; setBackground(Color.yellow); } public void update(Graphics g) { Dimension d = size(); int nWidth = d.width; int nHeight = d.height; if((m_MemImageDim == null) || (m_MemImageDim.width != nWidth) || (m_MemImageDim.height != nHeight)) { m_MemImageDim = new Dimension(nWidth, nHeight); m_MemImage = createImage(nWidth, nHeight); m_MemImage_Graphics = m_MemImage.getGraphics(); } Color fg = getForeground(); Color bg = getBackground(); m_MemImage_Graphics.setColor(bg); m_MemImage_Graphics.fillRect(0, 0, m_MemImageDim.width, m_MemImageDim.height); m_MemImage_Graphics.setColor(fg); m_MemImage_Graphics.drawString(m_Text, m_CurrentXPosition, 20); m_CurrentXPosition-; if(m_CurrentXPosition < -m_StringSize) m_CurrentXPosition = size().width; paint(g); } public void paint(Graphics g) { if(m_MemImage != null) g.drawImage(m_MemImage, 0, 0, null); } public void start() { if (m_ScrNoFlick == null) { m_ScrNoFlick = new Thread(this); m_ScrNoFlick.start(); } } public void stop() { if (m_ScrNoFlick != null) { m_ScrNoFlick.stop(); m_ScrNoFlick = null; } } public void run() { while (true) { try { repaint(); Thread.sleep(50); } catch (InterruptedException e) { stop(); } } } } В аплете ScrNoFlick, как и в предыдущем аплете SimpleScrol, мы пользуемся многопоточностью. Основной класс аплета реализует интерфейс Runnable, а определенный в этом классе метод run периодически перерисовывает окно аплета, вызывая в бесконечном цикле с задержкой метод repaint. Но основной интерес вызывают методы update и paint, выполняющие всю основную работу по изображению бегущей текстовой строки. Как мы уже говорили, метод update вызывается при обновлении окна аплета. В задачу нашей реализации метода update входит подготовка изображения сдвинутой текстовой строки, которое создается в оперативной памяти как объект класса Image. Затем метод update вызывает метод paint, рисующий это изображение в окне аплета. Предварительное стирание окна при этом выполнять не нужно. Процедуры подготовки изображения выполняются в несколько этапов. Прежде всего необходимо определить размеры окна аплета, так как создаваемое изображение класса Image должно иметь те же размеры, что и окно аплета: Dimension d = size(); int nWidth = d.width; int nHeight = d.height; Ширина и высота окна сохраняются в переменных nWidth и nHeight соответственно. В основном классе нашего аплета предусмотрено поле m_MemImageDim класса Dimension, в котором будут храниться размеры изображения. Так как изображение нужно создавать только один раз, на следующем шаге метод update проверяет, была ли выполнена эта операция и соответствуют ли размеры изображения размерам окна аплета: if((m_MemImageDim == null) || (m_MemImageDim.width != nWidth) || (m_MemImageDim.height != nHeight)) { . . . } Если изображение создано не было или его размеры не равны размерам окна аплета, выполняются следующие действия. Сначала метод update определяет необходимые размеры изображения, исходя из размеров окна аплета. Затем он создает изображение и получает для него контекст отображения: m_MemImageDim = new Dimension(nWidth, nHeight); m_MemImage = createImage(nWidth, nHeight); m_MemImage_Graphics = m_MemImage.getGraphics(); Изображение создается в оперативной памяти методом createImage. Что же касается контекста отображения, который будет применен для рисования, то он сохраняется в поле m_MemImage_Graphics. На следующем этапе метод update определяет цвет рисования и фона окна аплета и устанавливает в контексте отображения m_MemImage_Graphics цвет фона, соответствующий цвету фона окна аплета: Color fg = getForeground(); Color bg = getBackground(); m_MemImage_Graphics.setColor(bg); После установки цвета метод update закрашивает этим цветом изображение, пользуясь контекстом m_MemImage_Graphics: m_MemImage_Graphics.fillRect(0, 0, m_MemImageDim.width, m_MemImageDim.height); Далее в этом же контексте устанавливается такой же цвет фона, что и в окне аплета: m_MemImage_Graphics.setColor(fg); Теперь изображение в памяти готово для рисования в нем текстовой строки. Мы выполняем эту операцию в текущей позиции m_CurrentXPosition, а затем уменьшаем позицию на единицу: m_MemImage_Graphics.drawString(m_Text, m_CurrentXPosition, 20); m_CurrentXPosition-; В результате каждый раз при вызове метода update строка будет сдвигаться в изображении m_MemImage на один пиксел влево. Когда же текущая позиция становится меньше длины строки, эта позиция вновь устанавливается в начальное значение: if(m_CurrentXPosition < -m_StringSize) m_CurrentXPosition = size().width; Последнее, что делает метод update перед тем как вернуть управление, - это вызов метода paint: paint(g); Метод paint рисует подготовленное методом update изображение m_MemImage в окне аплета, пользуясь для этого методом drawImage: if(m_MemImage != null) g.drawImage(m_MemImage, 0, 0, null); В результате текстовая строка появится на экране в том состоянии, в котором она находилось на момент вызова метода paint. | ||||||||||||||||||||||
Работа в консоли | ||||||||||||||||||||||
Для создания апплета, который может быть запущен из командной строки консоли,
вы просто добавляете main( ) в ваш апплет, который создает экземпляр апплета
внутри JFrame.[66] В качестве простого примера давайте взглянем на измененный
Applet1b.java, который теперь может работать и как приложение, и как апплет:
import javax.swing.*; import java.awt.*; import com.bruceeckel.swing.*; public class Applet1c extends JApplet { public void init() { getContentPane().add(new JLabel("Applet!")); } // main() для приложения: public static void main(String[] args) { JApplet applet = new Applet1c(); JFrame frame = new JFrame("Applet1c"); // Для закрытия приложения: Console.setupClosing(frame); frame.getContentPane().add(applet); frame.setSize(100,50); applet.init(); applet.start(); frame.setVisible(true); } } | ||||||||||||||||||||||
Listeners | ||||||||||||||||||||||
class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } | ||||||||||||||||||||||
Кнопки (JButton) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.plaf.basic.*; import javax.swing.border.*; import com.bruceeckel.swing.*; public class Buttons extends JApplet { JButton jb = new JButton("JButton"); BasicArrowButton up = new BasicArrowButton( BasicArrowButton.NORTH), down = new BasicArrowButton( BasicArrowButton.SOUTH), right = new BasicArrowButton( BasicArrowButton.EAST), left = new BasicArrowButton( BasicArrowButton.WEST); public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(jb); cp.add(new JToggleButton("JToggleButton")); cp.add(new JCheckBox("JCheckBox")); cp.add(new JRadioButton("JRadioButton")); JPanel jp = new JPanel(); jp.setBorder(new TitledBorder("Directions")); jp.add(up); jp.add(down); jp.add(left); jp.add(right); cp.add(jp); } public static void main(String[] args) { Console.run(new Buttons(), 350, 100); } } | ||||||||||||||||||||||
Группы кнопок (ButtonGroup) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.border.*; import java.lang.reflect.*; import com.bruceeckel.swing.*; public class ButtonGroups extends JApplet { static String[] ids = { "June", "Ward", "Beaver", "Wally", "Eddie", "Lumpy", }; static JPanel makeBPanel(Class bClass, String[] ids) { ButtonGroup bg = new ButtonGroup(); JPanel jp = new JPanel(); String title = bClass.getName(); title = title.substring( title.lastIndexOf('.') + 1); jp.setBorder(new TitledBorder(title)); for(int i = 0; i < ids.length; i++) { AbstractButton ab = new JButton("failed"); try { // Получение динамического метода конструктора, // который принимает аргумент String: Constructor ctor = bClass.getConstructor( new Class[] { String.class }); // Создание нового объекта: ab = (AbstractButton)ctor.newInstance( new Object[]{ids[i]}); } catch(Exception ex) { System.err.println("can't create " + bClass); } bg.add(ab); jp.add(ab); } return jp; } public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(makeBPanel(JButton.class, ids)); cp.add(makeBPanel(JToggleButton.class, ids)); cp.add(makeBPanel(JCheckBox.class, ids)); cp.add(makeBPanel(JRadioButton.class, ids)); } public static void main(String[] args) { Console.run(new ButtonGroups(), 500, 300); } } | ||||||||||||||||||||||
Иконки (ImageIcon) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.*; import java.awt.event.*; import com.bruceeckel.swing.*; public class Faces extends JApplet { // Следующая информация о пути необходима // для запуска апплета непосредственно с диска: static String path = "C:/aaa-TIJ2-distribution/code/c13/"; static Icon[] faces = { new ImageIcon(path + "face0.gif"), new ImageIcon(path + "face1.gif"), new ImageIcon(path + "face2.gif"), new ImageIcon(path + "face3.gif"), new ImageIcon(path + "face4.gif"), }; JButton jb = new JButton("JButton", faces[3]), jb2 = new JButton("Disable"); boolean mad = false; public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); jb.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ if(mad) { jb.setIcon(faces[3]); mad = false; } else { jb.setIcon(faces[0]); mad = true; } jb.setVerticalAlignment(JButton.TOP); jb.setHorizontalAlignment(JButton.LEFT); } }); jb.setRolloverEnabled(true); jb.setRolloverIcon(faces[1]); jb.setPressedIcon(faces[2]); jb.setDisabledIcon(faces[4]); jb.setToolTipText("Yow!"); cp.add(jb); jb2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ if(jb.isEnabled()) { jb.setEnabled(false); jb2.setText("Enable"); } else { jb.setEnabled(true); jb2.setText("Disable"); } } }); cp.add(jb2); } public static void main(String[] args) { Console.run(new Faces(), 400, 200); } } | ||||||||||||||||||||||
Текстовые поля (JTextField) | ||||||||||||||||||||||
import javax.swing.*; import javax.swing.event.*; import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import com.bruceeckel.swing.*; public class TextFields extends JApplet { JButton b1 = new JButton("Get Text"), b2 = new JButton("Set Text"); JTextField t1 = new JTextField(30), t2 = new JTextField(30), t3 = new JTextField(30); String s = new String(); UpperCaseDocument ucd = new UpperCaseDocument(); public void init() { t1.setDocument(ucd); ucd.addDocumentListener(new T1()); b1.addActionListener(new B1()); b2.addActionListener(new B2()); DocumentListener dl = new T1(); t1.addActionListener(new T1A()); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(b1); cp.add(b2); cp.add(t1); cp.add(t2); cp.add(t3); } class T1 implements DocumentListener { public void changedUpdate(DocumentEvent e){} public void insertUpdate(DocumentEvent e){ t2.setText(t1.getText()); t3.setText("Text: "+ t1.getText()); } public void removeUpdate(DocumentEvent e){ t2.setText(t1.getText()); } } class T1A implements ActionListener { private int count = 0; public void actionPerformed(ActionEvent e) { t3.setText("t1 Action Event " + count++); } } class B1 implements ActionListener { public void actionPerformed(ActionEvent e) { if(t1.getSelectedText() == null) s = t1.getText(); else s = t1.getSelectedText(); t1.setEditable(true); } } class B2 implements ActionListener { public void actionPerformed(ActionEvent e) { ucd.setUpperCase(false); t1.setText("Inserted by Button 2: " + s); ucd.setUpperCase(true); t1.setEditable(false); } } public static void main(String[] args) { Console.run(new TextFields(), 375, 125); } } class UpperCaseDocument extends PlainDocument { boolean upperCase = true; public void setUpperCase(boolean flag) { upperCase = flag; } public void insertString(int offset, String string, AttributeSet attributeSet) throws BadLocationException { if(upperCase) string = string.toUpperCase(); super.insertString(offset, string, attributeSet); } } | ||||||||||||||||||||||
Бордюры | ||||||||||||||||||||||
import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.border.*; import com.bruceeckel.swing.*; public class Borders extends JApplet { static JPanel showBorder(Border b) { JPanel jp = new JPanel(); jp.setLayout(new BorderLayout()); String nm = b.getClass().toString(); nm = nm.substring(nm.lastIndexOf('.') + 1); jp.add(new JLabel(nm, JLabel.CENTER), BorderLayout.CENTER); jp.setBorder(b); return jp; } public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.setLayout(new GridLayout(2,4)); cp.add(showBorder(new TitledBorder("Title"))); cp.add(showBorder(new EtchedBorder())); cp.add(showBorder(new LineBorder(Color.blue))); cp.add(showBorder( new MatteBorder(5,5,30,30,Color.green))); cp.add(showBorder( new BevelBorder(BevelBorder.RAISED))); cp.add(showBorder( new SoftBevelBorder(BevelBorder.LOWERED))); cp.add(showBorder(new CompoundBorder( new EtchedBorder(), new LineBorder(Color.red)))); } public static void main(String[] args) { Console.run(new Borders(), 500, 300); } } | ||||||||||||||||||||||
Панели скроллирования (JScrollPane) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.border.*; import com.bruceeckel.swing.*; public class JScrollPanes extends JApplet { JButton b1 = new JButton("Text Area 1"), b2 = new JButton("Text Area 2"), b3 = new JButton("Replace Text"), b4 = new JButton("Insert Text"); JTextArea t1 = new JTextArea("t1", 1, 20), t2 = new JTextArea("t2", 4, 20), t3 = new JTextArea("t3", 1, 20), t4 = new JTextArea("t4", 10, 10), t5 = new JTextArea("t5", 4, 20), t6 = new JTextArea("t6", 10, 10); JScrollPane sp3 = new JScrollPane(t3, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), sp4 = new JScrollPane(t4, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), sp5 = new JScrollPane(t5, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS), sp6 = new JScrollPane(t6, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); class B1L implements ActionListener { public void actionPerformed(ActionEvent e) { t5.append(t1.getText() + "\n"); } } class B2L implements ActionListener { public void actionPerformed(ActionEvent e) { t2.setText("Inserted by Button 2"); t2.append(": " + t1.getText()); t5.append(t2.getText() + "\n"); } } class B3L implements ActionListener { public void actionPerformed(ActionEvent e) { String s = " Replacement "; t2.replaceRange(s, 3, 3 + s.length()); } } class B4L implements ActionListener { public void actionPerformed(ActionEvent e) { t2.insert(" Inserted ", 10); } } public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); // Создание бордюра для компонент: Border brd = BorderFactory.createMatteBorder( 1, 1, 1, 1, Color.black); t1.setBorder(brd); t2.setBorder(brd); sp3.setBorder(brd); sp4.setBorder(brd); sp5.setBorder(brd); sp6.setBorder(brd); // Инициализация слушателей и добавление компонент: b1.addActionListener(new B1L()); cp.add(b1); cp.add(t1); b2.addActionListener(new B2L()); cp.add(b2); cp.add(t2); b3.addActionListener(new B3L()); cp.add(b3); b4.addActionListener(new B4L()); cp.add(b4); cp.add(sp3); cp.add(sp4); cp.add(sp5); cp.add(sp6); } public static void main(String[] args) { Console.run(new JScrollPanes(), 300, 725); } } | ||||||||||||||||||||||
Мини редактор (JTextPane) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.*; import java.awt.event.*; import com.bruceeckel.swing.*; import com.bruceeckel.util.*; public class TextPane extends JApplet { JButton b = new JButton("Add Text"); JTextPane tp = new JTextPane(); static Generator sg = new Arrays2.RandStringGenerator(7); public void init() { b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ for(int i = 1; i < 10; i++) tp.setText(tp.getText() + sg.next() + "\n"); } }); Container cp = getContentPane(); cp.add(new JScrollPane(tp)); cp.add(BorderLayout.SOUTH, b); } public static void main(String[] args) { Console.run(new TextPane(), 475, 425); } } | ||||||||||||||||||||||
CheckBox-элементы (JCheckBox) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.event.*; import java.awt.*; import com.bruceeckel.swing.*; public class CheckBoxes extends JApplet { JTextArea t = new JTextArea(6, 15); JCheckBox cb1 = new JCheckBox("Check Box 1"), cb2 = new JCheckBox("Check Box 2"), cb3 = new JCheckBox("Check Box 3"); public void init() { cb1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ trace("1", cb1); } }); cb2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ trace("2", cb2); } }); cb3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ trace("3", cb3); } }); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(new JScrollPane(t)); cp.add(cb1); cp.add(cb2); cp.add(cb3); } void trace(String b, JCheckBox cb) { if(cb.isSelected()) t.append("Box " + b + " Set\n"); else t.append("Box " + b + " Cleared\n"); } public static void main(String[] args) { Console.run(new CheckBoxes(), 200, 200); } } | ||||||||||||||||||||||
Радио кнопки (JRadioButton) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.event.*; import java.awt.*; import com.bruceeckel.swing.*; public class RadioButtons extends JApplet { JTextField t = new JTextField(15); ButtonGroup g = new ButtonGroup(); JRadioButton rb1 = new JRadioButton("one", false), rb2 = new JRadioButton("two", false), rb3 = new JRadioButton("three", false); ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { t.setText("Radio button " + ((JRadioButton)e.getSource()).getText()); } }; public void init() { rb1.addActionListener(al); rb2.addActionListener(al); rb3.addActionListener(al); g.add(rb1); g.add(rb2); g.add(rb3); t.setEditable(false); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(t); cp.add(rb1); cp.add(rb2); cp.add(rb3); } public static void main(String[] args) { Console.run(new RadioButtons(), 200, 100); } } | ||||||||||||||||||||||
Выпадающие списки (JComboBox) | ||||||||||||||||||||||
public class ComboBoxes extends JApplet { String[] description = { "Ebullient", "Obtuse", "Recalcitrant", "Brilliant", "Somnescent", "Timorous", "Florid", "Putrescent" }; JTextField t = new JTextField(15); JComboBox c = new JComboBox(); JButton b = new JButton("Add items"); int count = 0; public void init() { for(int i = 0; i < 4; i++) c.addItem(description[count++]); t.setEditable(false); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ if(count < description.length) c.addItem(description[count++]); } }); c.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ t.setText("index: "+ c.getSelectedIndex() + " " + ((JComboBox)e.getSource()) .getSelectedItem()); } }); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(t); cp.add(c); cp.add(b); } public static void main(String[] args) { Console.run(new ComboBoxes(), 200, 100); } } | ||||||||||||||||||||||
Списки (JList) | ||||||||||||||||||||||
import javax.swing.*; import javax.swing.event.*; import java.awt.*; import java.awt.event.*; import javax.swing.border.*; import com.bruceeckel.swing.*; public class List extends JApplet { String[] flavors = { "Chocolate", "Strawberry", "Vanilla Fudge Swirl", "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", "Praline Cream", "Mud Pie" }; DefaultListModel lItems=new DefaultListModel(); JList lst = new JList(lItems); JTextArea t = new JTextArea(flavors.length,20); JButton b = new JButton("Add Item"); ActionListener bl = new ActionListener() { public void actionPerformed(ActionEvent e) { if(count < flavors.length) { lItems.add(0, flavors[count++]); } else { // Отключено, так как не осталось больше // вкусов для добавления в список b.setEnabled(false); } } }; ListSelectionListener ll = new ListSelectionListener() { public void valueChanged( ListSelectionEvent e) { t.setText(""); Object[] items=lst.getSelectedValues(); for(int i = 0; i < items.length; i++) t.append(items[i] + "\n"); } }; int count = 0; public void init() { Container cp = getContentPane(); t.setEditable(false); cp.setLayout(new FlowLayout()); // Создание бордюра для компонента: Border brd = BorderFactory.createMatteBorder( 1, 1, 2, 2, Color.black); lst.setBorder(brd); t.setBorder(brd); // Добавление первых четырех элементов в список for(int i = 0; i < 4; i++) lItems.addElement(flavors[count++]); // Добавление элементов в Панель Содержания для отображения cp.add(t); cp.add(lst); cp.add(b); // Регистрация слушателей событий lst.addListSelectionListener(ll); b.addActionListener(bl); } public static void main(String[] args) { Console.run(new List(), 250, 375); } } | ||||||||||||||||||||||
Закладки (JTabbedPane) | ||||||||||||||||||||||
import javax.swing.*; import javax.swing.event.*; import java.awt.*; import com.bruceeckel.swing.*; public class TabbedPane1 extends JApplet { String[] flavors = { "Chocolate", "Strawberry", "Vanilla Fudge Swirl", "Mint Chip", "Mocha Almond Fudge", "Rum Raisin", "Praline Cream", "Mud Pie" }; JTabbedPane tabs = new JTabbedPane(); JTextField txt = new JTextField(20); public void init() { for(int i = 0; i < flavors.length; i++) tabs.addTab(flavors[i], new JButton("Tabbed pane " + i)); tabs.addChangeListener(new ChangeListener(){ public void stateChanged(ChangeEvent e) { txt.setText("Tab selected: " + tabs.getSelectedIndex()); } }); Container cp = getContentPane(); cp.add(BorderLayout.SOUTH, txt); cp.add(tabs); } public static void main(String[] args) { Console.run(new TabbedPane1(), 350, 200); } } | ||||||||||||||||||||||
Окна сообщений (JOptionPane) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.event.*; import java.awt.*; import com.bruceeckel.swing.*; public class MessageBoxes extends JApplet { JButton[] b = { new JButton("Alert"), new JButton("Yes/No"), new JButton("Color"), new JButton("Input"), new JButton("3 Vals") }; JTextField txt = new JTextField(15); ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e){ String id = ((JButton)e.getSource()).getText(); if(id.equals("Alert")) JOptionPane.showMessageDialog(null, "There's a bug on you!", "Hey!", JOptionPane.ERROR_MESSAGE); else if(id.equals("Yes/No")) JOptionPane.showConfirmDialog(null, "or no", "choose yes", JOptionPane.YES_NO_OPTION); else if(id.equals("Color")) { Object[] options = { "Red", "Green" }; int sel = JOptionPane.showOptionDialog( null, "Choose a Color!", "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); if(sel != JOptionPane.CLOSED_OPTION) txt.setText( "Color Selected: " + options[sel]); } else if(id.equals("Input")) { String val = JOptionPane.showInputDialog( "How many fingers do you see?"); txt.setText(val); } else if(id.equals("3 Vals")) { Object[] selections = { "First", "Second", "Third" }; Object val = JOptionPane.showInputDialog( null, "Choose one", "Input", JOptionPane.INFORMATION_MESSAGE, null, selections, selections[0]); if(val != null) txt.setText( val.toString()); } } }; public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); for(int i = 0; i < b.length; i++) { b[i].addActionListener(al); cp.add(b[i]); } cp.add(txt); } public static void main(String[] args) { Console.run(new MessageBoxes(), 200, 200); } } | ||||||||||||||||||||||
Меню (JMenu) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.event.*; import java.awt.*; import com.bruceeckel.swing.*; public class SimpleMenus extends JApplet { JTextField t = new JTextField(15); ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e){ t.setText( ((JMenuItem)e.getSource()).getText()); } }; JMenu[] menus = { new JMenu("Winken"), new JMenu("Blinken"), new JMenu("Nod") }; JMenuItem[] items = { new JMenuItem("Fee"), new JMenuItem("Fi"), new JMenuItem("Fo"), new JMenuItem("Zip"), new JMenuItem("Zap"), new JMenuItem("Zot"), new JMenuItem("Olly"), new JMenuItem("Oxen"), new JMenuItem("Free") }; public void init() { for(int i = 0; i < items.length; i++) { items[i].addActionListener(al); menus[i%3].add(items[i]); } JMenuBar mb = new JMenuBar(); for(int i = 0; i < menus.length; i++) mb.add(menus[i]); setJMenuBar(mb); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(t); } public static void main(String[] args) { Console.run(new SimpleMenus(), 200, 75); } } | ||||||||||||||||||||||
Всплывающие меню (JPopupMenu) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.*; import java.awt.event.*; import com.bruceeckel.swing.*; public class Popup extends JApplet { JPopupMenu popup = new JPopupMenu(); JTextField t = new JTextField(10); public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(t); ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e){ t.setText( ((JMenuItem)e.getSource()).getText()); } }; JMenuItem m = new JMenuItem("Hither"); m.addActionListener(al); popup.add(m); m = new JMenuItem("Yon"); m.addActionListener(al); popup.add(m); m = new JMenuItem("Afar"); m.addActionListener(al); popup.add(m); popup.addSeparator(); m = new JMenuItem("Stay Here"); m.addActionListener(al); popup.add(m); PopupListener pl = new PopupListener(); addMouseListener(pl); t.addMouseListener(pl); } class PopupListener extends MouseAdapter { public void mousePressed(MouseEvent e) { maybeShowPopup(e); } public void mouseReleased(MouseEvent e) { maybeShowPopup(e); } private void maybeShowPopup(MouseEvent e) { if(e.isPopupTrigger()) { popup.show( e.getComponent(), e.getX(), e.getY()); } } } public static void main(String[] args) { Console.run(new Popup(), 300, 200); } } | ||||||||||||||||||||||
Рисунок | ||||||||||||||||||||||
import javax.swing.*; import javax.swing.event.*; import java.awt.*; import com.bruceeckel.swing.*; class SineDraw extends JPanel { static final int SCALEFACTOR = 200; int cycles; int points; double[] sines; int[] pts; SineDraw() { setCycles(5); } public void setCycles(int newCycles) { cycles = newCycles; points = SCALEFACTOR * cycles * 2; sines = new double[points]; pts = new int[points]; for(int i = 0; i < points; i++) { double radians = (Math.PI/SCALEFACTOR) * i; sines[i] = Math.sin(radians); } repaint(); } public void paintComponent(Graphics g) { super.paintComponent(g); int maxWidth = getWidth(); double hstep = (double)maxWidth/(double)points; int maxHeight = getHeight(); for(int i = 0; i < points; i++) pts[i] = (int)(sines[i] * maxHeight/2 * .95 + maxHeight/2); g.setColor(Color.red); for(int i = 1; i < points; i++) { int x1 = (int)((i - 1) * hstep); int x2 = (int)(i * hstep); int y1 = pts[i-1]; int y2 = pts[i]; g.drawLine(x1, y1, x2, y2); } } } public class SineWave extends JApplet { SineDraw sines = new SineDraw(); JSlider cycles = new JSlider(1, 30, 5); public void init() { Container cp = getContentPane(); cp.add(sines); cycles.addChangeListener(new ChangeListener(){ public void stateChanged(ChangeEvent e) { sines.setCycles( ((JSlider)e.getSource()).getValue()); } }); cp.add(BorderLayout.SOUTH, cycles); } public static void main(String[] args) { Console.run(new SineWave(), 700, 400); } } | ||||||||||||||||||||||
Окна диалогов (JDialog) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.event.*; import java.awt.*; import com.bruceeckel.swing.*; class MyDialog extends JDialog { public MyDialog(JFrame parent) { super(parent, "My dialog", true); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(new JLabel("Here is my dialog")); JButton ok = new JButton("OK"); ok.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ dispose(); // Закрытие диалога. } }); cp.add(ok); setSize(150,125); } } public class Dialogs extends JApplet { JButton b1 = new JButton("Dialog Box"); MyDialog dlg = new MyDialog(null); public void init() { b1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ dlg.show(); } }); getContentPane().add(b1); } public static void main(String[] args) { Console.run(new Dialogs(), 125, 75); } } | ||||||||||||||||||||||
HTML в Swing компонентах | ||||||||||||||||||||||
import javax.swing.*; import java.awt.event.*; import java.awt.*; import com.bruceeckel.swing.*; public class HTMLButton extends JApplet { JButton b = new JButton("<html><b><font size=+2>" + "<center>Hello!<br><i>Press me now!"); public void init() { b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ getContentPane().add(new JLabel("<html>"+ "<i><font size=+4>Kapow!")); // Производим перекомпоновку для // включения новой метки: validate(); } }); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(b); } public static void main(String[] args) { Console.run(new HTMLButton(), 200, 500); } } | ||||||||||||||||||||||
Слайдеры и индикатор выполнения (JProgressBar) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.event.*; import javax.swing.border.*; import com.bruceeckel.swing.*; public class Progress extends JApplet { JProgressBar pb = new JProgressBar(); JSlider sb = new JSlider(JSlider.HORIZONTAL, 0, 100, 60); public void init() { Container cp = getContentPane(); cp.setLayout(new GridLayout(2,1)); cp.add(pb); sb.setValue(0); sb.setPaintTicks(true); sb.setMajorTickSpacing(20); sb.setMinorTickSpacing(5); sb.setBorder(new TitledBorder("Slide Me")); pb.setModel(sb.getModel()); // Распределенная модель cp.add(sb); } public static void main(String[] args) { Console.run(new Progress(), 300, 200); } } | ||||||||||||||||||||||
Деревья (JTree) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.tree.*; import com.bruceeckel.swing.*; // Берется массив Strings и создается первый // элемент ноды, а оставшиеся оставляются: class Branch { DefaultMutableTreeNode r; public Branch(String[] data) { r = new DefaultMutableTreeNode(data[0]); for(int i = 1; i < data.length; i++) r.add(new DefaultMutableTreeNode(data[i])); } public DefaultMutableTreeNode node() { return r; } } public class Trees extends JApplet { String[][] data = { { "Colors", "Red", "Blue", "Green" }, { "Flavors", "Tart", "Sweet", "Bland" }, { "Length", "Short", "Medium", "Long" }, { "Volume", "High", "Medium", "Low" }, { "Temperature", "High", "Medium", "Low" }, { "Intensity", "High", "Medium", "Low" }, }; static int i = 0; DefaultMutableTreeNode root, child, chosen; JTree tree; DefaultTreeModel model; public void init() { Container cp = getContentPane(); root = new DefaultMutableTreeNode("root"); tree = new JTree(root); // Это добавляется для заботы о скроллировании: cp.add(new JScrollPane(tree), BorderLayout.CENTER); // Получение модели дерева: model =(DefaultTreeModel)tree.getModel(); JButton test = new JButton("Press me"); test.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ if(i < data.length) { child = new Branch(data[i++]).node(); // Что было последним, на чем вы щелкнули? chosen = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent(); if(chosen == null) chosen = root; // Модель будет создавать // соответствующие события. В ответ // дерево будет обновлять себя: model.insertNodeInto(child, chosen, 0); // Здесь помещается новая нода // в текущую выбранную ноду. } } }); // Изменение цвета кнопки: test.setBackground(Color.blue); test.setForeground(Color.white); JPanel p = new JPanel(); p.add(test); cp.add(p, BorderLayout.SOUTH); } public static void main(String[] args) { Console.run(new Trees(), 250, 250); } } | ||||||||||||||||||||||
Таблицы (JTable) | ||||||||||||||||||||||
import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.table.*; import javax.swing.event.*; import com.bruceeckel.swing.*; public class Table extends JApplet { JTextArea txt = new JTextArea(4, 20); // TableModel управляет всеми данными: class DataModel extends AbstractTableModel { Object[][] data = { {"one", "two", "three", "four"}, {"five", "six", "seven", "eight"}, {"nine", "ten", "eleven", "twelve"}, }; // Печатает данные при изменении таблицы: class TML implements TableModelListener { public void tableChanged(TableModelEvent e){ txt.setText(""); // Очистка for(int i = 0; i < data.length; i++) { for(int j = 0; j < data[0].length; j++) txt.append(data[i][j] + " "); txt.append("\n"); } } } public DataModel() { addTableModelListener(new TML()); } public int getColumnCount() { return data[0].length; } public int getRowCount() { return data.length; } public Object getValueAt(int row, int col) { return data[row][col]; } public void setValueAt(Object val, int row, int col) { data[row][col] = val; // Указывает на появление изменений: fireTableDataChanged(); } public boolean isCellEditable(int row, int col) { return true; } } public void init() { Container cp = getContentPane(); JTable table = new JTable(new DataModel()); cp.add(new JScrollPane(table)); cp.add(BorderLayout.SOUTH, txt); } public static void main(String[] args) { Console.run(new Table(), 350, 200); } } | ||||||||||||||||||||||
Создание Java-апплета для отображения карт | ||||||||||||||||||||||
- | ||||||||||||||||||||||
- | ||||||||||||||||||||||