Java圖形程式設計學習(4)Swing元件
1、元件內部的設計—以Swing按鈕為例
背景:MVC模式,即模型-檢視-控制器模式。Swing元件底層大多數都用到了該模式。接下來以按鈕為例分析這種模式。
(1)元件的模型類,一般是實現以Model結尾的介面。按鈕的模型類實現了ButtonModel介面。實現了該介面的類可以設定
ButtonModel介面中定義的按鈕的各種屬性,定義按鈕的狀態。DefaultButtonModel類就實現了這個介面。
(2)模型不儲存按鈕的圖示,即僅憑模型不能知道按鈕的外觀,這些外觀由檢視控制。
(3)控制器負責處理使用者輸入事件,如點選滑鼠。然後覺得是否把這些事件轉化成對模型或檢視的改變。並不是所有的元件
都有專門的控制器物件。
2、佈局管理器
作用:通常元件放置在容器中,佈局管理器決定容器中的元件具體放置的位置和大小。
分類:
流佈局管理器(面板的預設佈局管理器):居中,一行滿了會換行。
邊框佈局管理器(JFrame的內容窗格的預設佈局管理器):選擇將元件放在內容窗格的中部,北部等。
網格佈局管理器:按行列排列所有的元件,並且每個單元的大小是一樣的。
注:可以組合使用
package comp; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JPanel; /** * 設計一個計算器 */ public class CalculatorPanel extends JPanel{ private JButton display; private JPanel panel; private double result; private String lastCommand; private boolean start; //返回元件的首選大小 public Dimension getPreferredSize() { return new Dimension(300,200 ); } public CalculatorPanel() { //構造一個新的邊界佈局,在元件之間沒有間隙。 setLayout( new BorderLayout() ); result = 0; lastCommand = "="; start = true; //用一個不可以點選的按鈕作為計算器的顯示欄 display = new JButton("0"); display.setEnabled(false); add( display, BorderLayout.NORTH );//邊框佈局的使用 //數字鍵和符號鍵會發出兩種事件,分別處理 ActionListener insert = new InsertAction(); ActionListener command = new CommandAction(); panel = new JPanel(); panel.setLayout(new GridLayout(4, 4));//網格佈局的使用,4行4列 //向panel中新增按鈕,並且該方法會讓按鈕繫結一個監聽器 addButton("7", insert); addButton("8", insert); addButton("9", insert); addButton("/", command); addButton("4", insert); addButton("5", insert); addButton("6", insert); addButton("*", command); addButton("1", insert); addButton("2", insert); addButton("3", insert); addButton("-", command); addButton("0", insert); addButton(".", insert); addButton("=", command); addButton("+", command); add( panel, BorderLayout.CENTER );//邊框佈局的使用 } private void addButton(String label, ActionListener listener) { JButton button = new JButton( label ); button.addActionListener(listener); panel.add(button); } private class InsertAction implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { //返回與此操作相關聯的命令字串 String input = e.getActionCommand(); //開始時start是true,若按了任意數字鍵,先將顯示欄清空 if( start ) { display.setText(""); start = false; } //將原有的數字和現在點選的數字鍵字元拼接 display.setText(display.getText() + input); } } private class CommandAction implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); //剛開始時的符號只有 - 能算數 if( start ) { //這裡-是負號的意思,表示負數 if( command.equals("-") ) { display.setText(command); start = false; }else { lastCommand = command; } }else { //預設設定了一個result和一個輸入做運算,得到的結果放入result中 calculate(Double. parseDouble( display.getText() )); lastCommand = command; start = true; } } } public void calculate(double x) { if( lastCommand.equals("+") ) result += x; else if( lastCommand.equals("-") ) result -= x; else if( lastCommand.equals("*") ) result *= x; else if( lastCommand.equals("/") ) result /= x; else if( lastCommand.equals("=") ) result = x; display.setText(""+result); } }
package comp; import java.awt.EventQueue; import javax.swing.JFrame; public class CalFrame extends JFrame{ public CalFrame() { add(new CalculatorPanel()); pack();//更加元件的首選大小,調整視窗 } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new CalFrame();//初始化視窗 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設定:關閉視窗,則程式退出 frame.setVisible(true);//顯示視窗 } }); } }
3、文字輸入
(1)文字域:只接受單行文字的輸入
需要掌握的API:
JTextField textField = new JTextField( "hahahha", 20 );
JTextField textField = new JTextField( 20 );
textField.setText("Hello hahaha");
String text = textField.getText().trim();//返回文字域中的內容,去掉前後空格
(2)密碼域:只接受單行文字的輸入,且輸入內容不會顯示出來
需要掌握的API:
JPasswordField(String text, int col);
void setEchoChar(char echo);//設定回顯字元,0表示預設的回顯字元
char[] getPassword(); //返回密碼域中的文字
(3)文字區:接受多行文字
需要掌握的API:
JTextArea textArea = new JTextArea(8, 40); //8行40列的文字區
textArea.setLineWrap(true);//文字超出文字區會被剪裁,開啟換行特性避免被裁剪;換行只是視覺效果,文字中間沒有換行符
JScrollPane scrollPane = new JScrollPane(textArea );//文字區沒有滾動條,將文字區放到滾動窗格中
package comp;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
public class TextComFrame extends JFrame{
public TextComFrame() {
JTextField textField = new JTextField();
JPasswordField passwordField = new JPasswordField();
JPanel northPanel = new JPanel();
//設定面板是2*2的網格佈局
northPanel.setLayout(new GridLayout(2,2));
//給textField文字框新增一個標籤;標籤位置在第一行的第一個網格中居中
northPanel.add(new JLabel("User name: ", SwingConstants.CENTER));
northPanel.add(textField);
//給passwordField文字框新增一個標籤;
northPanel.add(new JLabel("Password: ", SwingConstants.CENTER));
northPanel.add(passwordField);
add( northPanel, BorderLayout.NORTH );
JTextArea textArea = new JTextArea( 8,20 );
JScrollPane scrollPane = new JScrollPane( textArea );
add( scrollPane, BorderLayout.CENTER );
JPanel southPanel = new JPanel();
JButton insertButton = new JButton( "Insert" );
southPanel.add(insertButton);
insertButton.addActionListener(
event -> textArea.append(
"User name: " + textField.getText() +
" Password: " +new String(passwordField.getPassword()) + "\n" )
);
add( southPanel, BorderLayout.SOUTH );
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new TextComFrame();//初始化視窗
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設定:關閉視窗,則程式退出
frame.setVisible(true);//顯示視窗
}
});
}
}
4、選擇元件
(1)複選框:選中或者不選;
JCheckBox( String label );//構造一個複選框,預設是沒有被選中
JCheckBox( String label, Icon icon );
JCheckBox( String label, boolean state );//用給定的標籤和初始化狀態構造一個複選框
boolean isSelected();
void setSelected( boolean state );//設定複選框的狀態
(2)單選鈕組:只選擇多個選項中的一個;選擇另一個前一個自動取消;
JRadioButton( String label, Icon icon ); //構造一個單選鈕,預設是沒有被選中
JRadioButton( String label, boolean state ); //用給定的標籤和初始化狀態構造一個單選鈕
void add( AbstractButton b ); //將按鈕新增到組中
ButtonModel getSelection(); //返回被選中的按鈕的按鈕模型
String getActionCommand(); //返回按鈕模型的動作命令
void setActionCommand( String s ); //設定按鈕及模型的動作命令
注意:一個視窗,若有多組單選按鈕,就需要用視覺化的形式指明哪些按鈕屬於同一組,邊框解決該問題。
(3)組合框:若覺得單選按鈕佔據的螢幕空間太大,就可以使用組合框(下拉框)。
JComBox<String> comb = new JComBox<String>();
boolean isEditable();
void setEditable( boolean b );
void addItem( Object item );
void insetItemAt( Object item, int index );
void removeItem( Object item );
void removeItemAt( int index );
void removeAllItems();
Object getSelectedItem();
(4)滑動條:讓使用者從一組離散值中進行選擇;
JSlider();//預設的滑動條:方向水平,0-100,初始值50
JSlider( int direction );
JSlider( int min, int max );
JSlider( int min, int max, int initialValue );
JSlider( int direction, int min, int max, int initialValue );
void setPaintTicks( boolean b );//顯示標尺
void setMajorTickSpacing( int units );//用給定的滑動條單位的倍數設定大標尺
void setMinorTickSpacing( int units );//用給定的滑動條單位的倍數設定小標尺
void setPaintLabels( boolean b ); //顯示標尺標籤
void setLabelTable( Dictionary table );//設定用於作為標尺標籤的元件
void setSnapToTicks( boolean b ); //true 則每一次調整後滑塊都要對齊到最接近的標尺處
void setPaintTrack( boolean b ); //true 則顯示滑動條滑動的軌跡
package comp;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class CheckBoxFrame extends JFrame{
private JLabel label;
//複選框 bold; 選中則使文字變粗
private JCheckBox bold;
//複選框italic; 選中則使文字斜體
private JCheckBox italic;
public CheckBoxFrame() {
label = new JLabel("-----------用來測試複選框的作用---------");
label.setFont( new Font("Serif", Font.BOLD, 24) );
add( label, BorderLayout.CENTER );
//監聽器對複選框的響應;選中則改變標籤字型
ActionListener listener = event ->{
int mode = 0;
if( bold.isSelected() ) mode += Font.BOLD;
if( italic.isSelected() ) mode += Font.ITALIC;
label.setFont(new Font( "Serif", mode, 24 ));
};
JPanel buttonPanel = new JPanel();
bold = new JCheckBox( "Bold" );
bold.addActionListener(listener);
bold.setSelected(true);
buttonPanel.add(bold);
italic = new JCheckBox( "Italic" );
italic.addActionListener(listener);
buttonPanel.add(italic);
add( buttonPanel, BorderLayout.SOUTH );
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new CheckBoxFrame();//初始化視窗
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設定:關閉視窗,則程式退出
frame.setVisible(true);//顯示視窗
}
});
}
}
package comp;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class RadioButtonFrame extends JFrame{
private JLabel label;
private ButtonGroup group;
private JPanel buttonPanel;
public RadioButtonFrame() {
label = new JLabel( "測試單選按鈕例子" );
label.setFont(new Font( "Serif", Font.PLAIN, 36 ));
add( label, BorderLayout.CENTER );
buttonPanel = new JPanel();
group = new ButtonGroup();
addRadioButton("Small", 8);
addRadioButton("Medium", 12);
addRadioButton("Large", 18);
addRadioButton("Extra large", 36);
add( buttonPanel, BorderLayout.SOUTH );
pack();
}
public void addRadioButton( String name, int size ) {
boolean selected = size == 36;
JRadioButton button = new JRadioButton( name, selected );
group.add(button);
buttonPanel.add(button);
ActionListener listener = event -> label.setFont(new Font( "Serif", Font.PLAIN, size ));
button.addActionListener(listener);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new RadioButtonFrame();//初始化視窗
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設定:關閉視窗,則程式退出
frame.setVisible(true);//顯示視窗
}
});
}
}
package comp;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.Border;
public class BorderFrame extends JFrame{
private JPanel demoPanel;
private JPanel buttonPanel;
private ButtonGroup group;
public BorderFrame() {
demoPanel = new JPanel();
buttonPanel = new JPanel();
group = new ButtonGroup();
addRadioButton( "Lowered bevel", BorderFactory.createLoweredBevelBorder() );
addRadioButton( "Raised bevel", BorderFactory.createRaisedBevelBorder() );
addRadioButton( "Etched bevel", BorderFactory.createEtchedBorder() );
addRadioButton( "Line bevel", BorderFactory.createLineBorder(Color.BLUE) );
addRadioButton( "Matte bevel", BorderFactory.createMatteBorder(10, 10, 10, 10,Color.BLUE ) );
addRadioButton( "Empty bevel", BorderFactory.createEmptyBorder() );
Border etched = BorderFactory.createEtchedBorder();
Border titled = BorderFactory.createTitledBorder(etched, "Border types" );
buttonPanel.setBorder(titled);
setLayout(new GridLayout(2, 1));
add(buttonPanel);
add(demoPanel);
pack();
}
public void addRadioButton( String buttonName, Border b ) {
boolean selected = buttonName == "Empty bevel";
JRadioButton button = new JRadioButton( buttonName, selected );
//給指定的按鈕,設定邊框
button.addActionListener(event -> demoPanel.setBorder(b));
group.add(button);
buttonPanel.add(button);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new BorderFrame();//初始化視窗
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設定:關閉視窗,則程式退出
frame.setVisible(true);//顯示視窗
}
});
}
}
package comp;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class ComboBoxFrame extends JFrame{
private JComboBox<String> faceCombo;
private JLabel label;
public ComboBoxFrame() {
label = new JLabel("測試下拉框的例子");
label.setFont(new Font( "Serif", Font.PLAIN,24 ));
add( label, BorderLayout.CENTER );
faceCombo = new JComboBox<String>();
faceCombo.addItem("Serif");
faceCombo.addItem("SansSerif");
faceCombo.addItem("Monospaced");
faceCombo.addItem("Dialog");
faceCombo.addItem("DialogInput");
faceCombo.addActionListener(
event -> label.setFont(new Font(faceCombo.getItemAt(faceCombo.getSelectedIndex()), Font.PLAIN, 24))
);
faceCombo.addActionListener(
event -> System.out.println(faceCombo.getItemAt(faceCombo.getSelectedIndex()))
);
JPanel comboPanel = new JPanel();
comboPanel.add(faceCombo);
add(comboPanel, BorderLayout.SOUTH );
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new ComboBoxFrame();//初始化視窗
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設定:關閉視窗,則程式退出
frame.setVisible(true);//顯示視窗
}
});
}
}
package comp;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.util.Dictionary;
import java.util.Hashtable;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeListener;
public class SliderFrame extends JFrame{
private JPanel sliderPanel;
private JTextField textField;
private ChangeListener listener;
public SliderFrame() {
sliderPanel = new JPanel();
sliderPanel.setLayout(new GridLayout(10,1));
//通過監聽器獲取滑動條當前值
listener = event -> {
JSlider source = (JSlider)event.getSource();
textField.setText(""+source.getValue());
};
//第一個
JSlider slider = new JSlider();
textField = new JTextField();
addSlider( slider, "Plain" );
//第二個
slider = new JSlider();
slider.setPaintTicks(true);//顯示標尺
slider.setMajorTickSpacing(20);//大格為20單位
slider.setMinorTickSpacing(5);//小格為5單位
addSlider( slider, "Ticks" );
//第三個
slider = new JSlider();
slider.setPaintTicks(true);
slider.setSnapToTicks(true);//每一次調整後,滑塊都會對齊到最近的標尺處
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(5);
addSlider( slider, "Snap to ticks" );
//第4個
slider = new JSlider();
slider.setPaintTicks(true);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(5);
slider.setPaintTrack(false);//不顯示滑動條滑動的軌跡
addSlider( slider, "No track" );
//第5個
slider = new JSlider();
slider.setPaintTicks(true);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(5);
slider.setInverted(true);//最左端是100,最右端是0
addSlider( slider, "Inverted" );
//第6個
slider = new JSlider();
slider.setPaintTicks(true);
slider.setPaintLabels(true);//設定標尺標籤,預設是數字,標明大格單位
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(5);
addSlider( slider, "Labels" );
//第6個
slider = new JSlider();
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(5);
Dictionary<Integer, Component> labelTable = new Hashtable<>();
labelTable.put(0, new JLabel("A"));
labelTable.put(20, new JLabel("B"));
labelTable.put(40, new JLabel("C"));
labelTable.put(60, new JLabel("D"));
labelTable.put(80, new JLabel("E"));
labelTable.put(100, new JLabel("F"));
slider.setLabelTable(labelTable);
addSlider(slider, "Custom labels");
//第7個;沒有對應圖片故不顯示圖片標籤
slider = new JSlider();
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setSnapToTicks(true);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(20);
labelTable = new Hashtable<>();
labelTable.put(0, new JLabel(new ImageIcon("nine.gif")));
labelTable.put(20, new JLabel(new ImageIcon("nine.gif")));
labelTable.put(40, new JLabel(new ImageIcon("nine.gif")));
labelTable.put(60, new JLabel(new ImageIcon("nine.gif")));
labelTable.put(80, new JLabel(new ImageIcon("nine.gif")));
labelTable.put(100, new JLabel(new ImageIcon("nine.gif")));
slider.setLabelTable(labelTable);
addSlider(slider, "Icon labels");
textField = new JTextField();
add( sliderPanel, BorderLayout.CENTER );
add( textField, BorderLayout.SOUTH );//textField用來顯示滑塊所指的資料
pack();
}
//新增滑動條的方法
public void addSlider( JSlider s, String description ) {
s.addChangeListener(listener);
JPanel panel = new JPanel();
panel.add(s);
panel.add(new JLabel(description));
panel.setAlignmentX(Component.LEFT_ALIGNMENT);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = sliderPanel.getComponentCount();
gbc.anchor = GridBagConstraints.WEST;
sliderPanel.add(panel, gbc);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new SliderFrame();//初始化視窗
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設定:關閉視窗,則程式退出
frame.setVisible(true);//顯示視窗
}
});
}
}
5、選單
package comp;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.KeyStroke;
public class MenuFrame extends JFrame{
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
private Action saveAction;
private Action saveAsAction;
private JCheckBoxMenuItem readonlyItem;
private JPopupMenu popup;
//動作
class TestAction extends AbstractAction{
public TestAction( String name ) {
super( name );
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println( getValue( Action.NAME ) + " selected." );
}
}
public MenuFrame() {
setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
//File是一級選單
JMenu fileMenu = new JMenu("File");
//File下面的二級選單有:New, Open, Save, Save As, Exit
fileMenu.add(new TestAction("New"));
//給Open選單項新增快捷鍵
JMenuItem openItem = fileMenu.add(new TestAction("Open"));
openItem.setAccelerator(KeyStroke.getKeyStroke("ctrl 0"));
//將一個分隔符行新增到File選單中
fileMenu.addSeparator();
//給Save選單項新增快捷鍵
saveAction = new TestAction("Save");
JMenuItem saveItem = fileMenu.add(saveAction);
saveItem.setAccelerator(KeyStroke.getKeyStroke("ctrl S"));
//新增Save As選單項
saveAsAction = new TestAction("Save As");
fileMenu.add(saveAsAction);
fileMenu.addSeparator();
//新增Exit選單項
fileMenu.add(new AbstractAction("Exit") {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
//==============================================
//readonlyItem是複選框選單項
readonlyItem = new JCheckBoxMenuItem( "Read-only" );
readonlyItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//表示勾選了Read-only複選框,就不能點選Save或者Save As選單項了
boolean saveOk = !readonlyItem.isSelected();
saveAction.setEnabled(saveOk);
saveAsAction.setEnabled(saveOk);
}
});
//group是單選按鈕組;其中有Insert和Overtype兩個單選按鈕,即選了其中一個,另一個就會失選; 設定insert初始被選中
ButtonGroup group = new ButtonGroup();
JRadioButtonMenuItem isertItem = new JRadioButtonMenuItem("Insert");
isertItem.setSelected(true);
JRadioButtonMenuItem overtypeItem = new JRadioButtonMenuItem("Overtype");
group.add(isertItem);
group.add(overtypeItem);
//Edit是一級選單項,下面包括了Cut, Copy, Paste, Options 4個二級選單項
//Options是二級選單項,下面又包括readonlyItem,isertItem,overtypeItem3個三級選單項
Action cutAction = new TestAction("Cut");
cutAction.putValue(Action.SMALL_ICON, new ImageIcon("cut.gif"));
Action copyAction = new TestAction("Copy");
copyAction.putValue(Action.SMALL_ICON, new ImageIcon("copy.gif"));
Action pasteAction = new TestAction("Paste");
pasteAction.putValue(Action.SMALL_ICON, new ImageIcon("paste.gif"));
JMenu editMenu = new JMenu("Edit");
editMenu.add(cutAction);
editMenu.add(copyAction);
editMenu.add(pasteAction);
JMenu optionMenu = new JMenu("Options");
optionMenu.add(readonlyItem);
optionMenu.addSeparator();;
optionMenu.add(isertItem);
optionMenu.add(overtypeItem);
editMenu.addSeparator();
editMenu.add(optionMenu);
//=============================================
//Help是一級選單項,下面有Index, About兩個二級選單項
JMenu helpMenu = new JMenu("Help");
helpMenu.setMnemonic('H');//給H字母新增快捷鍵;可以ALT+H喚醒Help選單
JMenuItem indexItem = new JMenuItem("Index");
indexItem.setMnemonic('I');
helpMenu.add(indexItem);
Action aboutAction = new TestAction("About");
//給字母A新增快捷鍵,即直接按A就能喚醒About選單項;前提是Help已經喚醒
aboutAction.putValue(Action.MNEMONIC_KEY, new Integer('A'));
helpMenu.add(aboutAction);
//選單欄,將所有一級選單項放入其中
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(helpMenu);
//彈出選單;/點選滑鼠右鍵,彈出選單
popup = new JPopupMenu();
popup.add(cutAction);
popup.add(copyAction);
popup.add(pasteAction);
JPanel panel = new JPanel();
//點選滑鼠右鍵,彈出選單
panel.setComponentPopupMenu(popup);
add(panel);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new MenuFrame();//初始化視窗
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設定:關閉視窗,則程式退出
frame.setVisible(true);//顯示視窗
}
});
}
}
6、工具欄
工具欄是在程式中提供的快速訪問常用命令的按鈕欄;工具欄可以隨處移動;
package comp;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JToolBar;
public class ToolBarFrame extends JFrame{
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT =200;
private JPanel panel;
public ToolBarFrame() {
setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
panel = new JPanel();
add( panel, BorderLayout.CENTER );
Action blueAction = new ColorAction( "Blue", new ImageIcon("blue-ball.gif"), Color.BLUE );
Action yellowAction = new ColorAction( "Yellow", new ImageIcon("yellow-ball.gif"), Color.YELLOW );
Action redAction = new ColorAction( "Red", new ImageIcon("yed-ball.gif"), Color.RED );
Action exitAction = new AbstractAction( "Exit", new ImageIcon("exit.gif") ) {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
};
exitAction.putValue(Action.SHORT_DESCRIPTION, "Exit");
JToolBar bar = new JToolBar();
bar.add(blueAction);//返回的是一個按鈕,即相當於在工具欄中增加一個按鈕
bar.add(yellowAction);
bar.add(redAction);
bar.addSeparator();
bar.add(exitAction);
add(bar,BorderLayout.NORTH);
//將Action物件新增到選單欄中
JMenu menu = new JMenu("Color");
menu.add(yellowAction);
menu.add(blueAction);
menu.add(redAction);
menu.add(exitAction);
JMenuBar menuBar = new JMenuBar();
menuBar.add(menu);
setJMenuBar(menuBar);
}
//動作
class ColorAction extends AbstractAction{
public ColorAction( String name, Icon icon, Color c ) {
putValue(Action.NAME, name);
putValue(Action.SMALL_ICON, icon);
putValue(Action.SHORT_DESCRIPTION, name+" background");
putValue("Color", c);
}
@Override
public void actionPerformed(ActionEvent e) {
Color c = (Color) getValue("Color");
panel.setBackground(c);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new ToolBarFrame();//初始化視窗
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設定:關閉視窗,則程式退出
frame.setVisible(true);//顯示視窗
}
});
}
}
7、對話方塊
(1)模式對話方塊:在對話方塊關閉之前,應用程式不能繼續執行
(2)無模式對話方塊:比如工具欄
package comp;
import java.awt.BorderLayout;
import java.awt.Dialog;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class DialogFrame extends JFrame{
private AboutDialog dialog;
public DialogFrame() {
setSize(300, 200);
JMenuBar menuBar = new JMenuBar();
setJMenuBar(menuBar);
JMenu fileMenu = new JMenu("File");
menuBar.add(fileMenu);
JMenuItem aboutItem = new JMenuItem("About");
aboutItem.addActionListener(e -> {
if(dialog == null) {
dialog = new AboutDialog(DialogFrame.this);
}
dialog.setVisible(true);
});
fileMenu.add(aboutItem);
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.addActionListener(e -> System.exit(0));
fileMenu.add(exitItem);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new DialogFrame();//初始化視窗
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設定:關閉視窗,則程式退出
frame.setVisible(true);//顯示視窗
}
});
}
}
class AboutDialog extends Dialog{
public AboutDialog(JFrame owner) {
//構造一個對話方塊 owner表示對話方塊的擁有者,About DialogTest表示對話方塊的標題,true代表這是模式對話方塊
super(owner, "About DialogTest", true);
setSize(200, 200);
add(new JLabel("<html><h1><i>Core java</i></h1><hr>By Cay Horstman</html>" ),BorderLayout.CENTER );
JButton ok = new JButton("ok");
ok.addActionListener(event -> setVisible(false));
JPanel panel = new JPanel();
panel.add(ok);
add(panel, BorderLayout.SOUTH);
}
}