Draw a Circle in Jscrollpane
Java Programming Tutorial
Programming Graphical User Interface (GUI) - Part 2
JDK demo includes a binder "jfc
", which has many interesting demo on Swing and Java2D.
More on Swing'southward JComponents
The class hierarchy of Swing's top-level containers (JFrame
, JDialog
, JApplet
) are as follows. These top-level Swing containers are heavyweight, that rely on the underlying windowing subsystem of the native platform.
The class hierarchy of Swing'due south JComponent
south is as follows. JComponent
and its descendants are lightweight components.
ImageIcon
Many Swing's JComponent
s (such equally JLabel
and JButton
) back up a text label and an epitome icon. For example, the figure shows three buttons: one with text label, i with an image icon, and one with both text and icon.
The javax.swing.ImageIcon
class models an image icon. An ImageIcon
is a fixed-size pic, typically small, and mainly used for decorating GUI components. The ImageIcon
form implements javax.swing.Icon
interface, and hence, often upcasted and referenced every bit Icon
.
To construct an ImageIcon
, provide the image filename or URL. Image file type of GIF, PNG, JPG and BMP are supported. For case,
String imgFilename = "images/duke.png"; ImageIcon iconDuke = new ImageIcon(imgFilename); ImageIcon iconDuke = null; String imgFilename = "images/duke.png"; java.net.URL imgURL = getClass().getClassLoader().getResource(imgFilename); if (imgURL != null) { iconDuke = new ImageIcon(imgURL); } else { Organization.err.println("Couldn't find file: " + imgFilename); }
Using URL is more flexible as it tin access resource in a JAR file, and produces an fault message if the file does not exist (which results in a goose egg
URL).
Many JComponents
(such as JLabel
, JButton
) accepts an ImageIcon
in its constructor, or via the setIcon()
method. For example,
ImageIcon iconDuke = null; String imgFilename = "images/duke.gif"; URL imgURL = getClass().getClassLoader().getResource(imgFilename); if (imgURL != zilch) { iconDuke = new ImageIcon(imgURL); } else { Organisation.err.println("Couldn't notice file: " + imgFilename); } JLabel lbl = new JLabel("The Duke", iconDuke, JLabel.CENTER); lbl.setBackground(Color.LIGHT_GRAY); lbl.setOpaque(true); Container cp = getContentPane(); cp.add(lbl);
An ImageIcon
uses an java.awt.Image
object to hold the image data. Yous can retrieve this Paradigm
object via the ImageIcon
'south getImage()
method. The Image
object is used in the drawImage()
method for custom drawing (which shall exist discussed later).
Setting the Appearances and Properties of JComponents
Most of the Swing Components supports these features:
- Text and icon.
- Keyboard short-cut (called mnemonics), eastward.m., activated via the "Alt" fundamental in Windows System.
- Tool tips: display when the mouse-pointer pauses on the component.
- Await and feel: customized appearance and user interaction for the operating platform.
- Localization: unlike languages for dissimilar locale.
All JComponents
(such as JPanel
, JLabel
, JTextField
and JButton
) back up these fix methods to set their appearances and backdrop:
public void setBackground(Color bgColor) public void setForeground(Color fgcolor) public void setFont(Font font) public void setBorder(Border edge) public void setPreferredSize(Dimension dim) public void setMaximumSize(Dimension dim) public void setMinimumSize(Dimension dim) public void setOpaque(boolean isOpaque) public void setToolTipText(Cord toolTipMsg)
Swing'due south JLabel
and buttons (AbstractButton
subclasses): support both text and icon, which can exist specified in the constructor or via the setters.
public void setText(String strText) public void setIcon(Icon defaultIcon) public void setHorizontalAlignment(int alignment) public void setVerticalAlignment(int alignment) public void setHorizontalTextPosition(int textPosition) public void setVerticalTextPosition(int textPosition)
JTextField
supports:
public void setHorizontalAlignment(int alignment)
Swing'south buttons support mnemonic (to be triggered via keyboard short-cut with alt key).
public void setMnemonic(int mnemonic)
Example
This instance creates 3 JComponents
: a JLabel
, a JTextField
and a JButton
, and sets their appearances (background and foreground colors, font, preferred size and opacity). It also sets the horizontal text alignment for the JTextField
.
Images:
1 2 three 4 5 6 vii viii 9 10 11 12 13 14 xv 16 17 18 xix twenty 21 22 23 24 25 26 27 28 29 xxx 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 threescore 61 62 63 64 65 66 67 68 69 lxx 71 72 73 74 75 76 77 78 79 fourscore 81 82 83 84 85 86 87 88 89 90 91 92 | import java.awt.*; import java.awt.issue.*; import coffee.net.URL; import javax.swing.*; @SuppressWarnings("series") public grade SwingJComponentSetterTest extends JFrame { private String imgCrossFilename = "images/cantankerous.gif"; private String imgNoughtFilename = "images/nought.gif"; public SwingJComponentSetterTest() { ImageIcon iconCross = null; ImageIcon iconNought = nothing; URL imgURL = getClass().getClassLoader().getResource(imgCrossFilename); if (imgURL != null) { iconCross = new ImageIcon(imgURL); } else { Organization.err.println("Couldn't find file: " + imgCrossFilename); } imgURL = getClass().getClassLoader().getResource(imgNoughtFilename); if (imgURL != zero) { iconNought = new ImageIcon(imgURL); } else { System.err.println("Couldn't find file: " + imgNoughtFilename); } Container cp = getContentPane(); cp.setLayout(new FlowLayout(FlowLayout.CENTER, 10, x)); JLabel characterization = new JLabel("JLabel", iconCross, SwingConstants.CENTER); label.setFont(new Font(Font.DIALOG, Font.ITALIC, 14)); label.setOpaque(true); label.setBackground(new Color(204, 238, 241)); characterization.setForeground(Color.RED); label.setPreferredSize(new Dimension(120, 80)); characterization.setToolTipText("This is a JLabel"); cp.add(label); JButton push = new JButton(); push button.setText("Push"); push.setIcon(iconNought); push.setVerticalAlignment(SwingConstants.BOTTOM); push.setHorizontalAlignment(SwingConstants.RIGHT); push.setHorizontalTextPosition(SwingConstants.LEFT); push button.setVerticalTextPosition(SwingConstants.TOP); push button.setFont(new Font(Font.SANS_SERIF, Font.Assuming, 15)); button.setBackground(new Color(231, 240, 248)); button.setForeground(Colour.BLUE); button.setPreferredSize(new Dimension(150, 80)); button.setToolTipText("This is a JButton"); button.setMnemonic(KeyEvent.VK_B); cp.add together(push); JTextField textField = new JTextField("Text Field", fifteen); textField.setFont(new Font(Font.DIALOG_INPUT, Font.Obviously, 12)); textField.setForeground(Color.RED); textField.setHorizontalAlignment(JTextField.Right); textField.setToolTipText("This is a JTextField"); cp.add(textField); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("JComponent Test"); setLocationRelativeTo(null); setSize(500, 150); setVisible(true); System.out.println(label); Arrangement.out.println(button); Organisation.out.println(textField); } public static void master(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new SwingJComponentSetterTest(); } }); } } |
javax.swing.JLabel[, 41, 10, 120x80, alignmentX=0.0, alignmentY=0.0, border=, flags=25165832, maximumSize=, minimumSize=, preferredSize=java.awt.Dimension[width=120,superlative=lxxx], defaultIcon=file:.../cantankerous.gif, disabledIcon=, horizontalAlignment=Centre, horizontalTextPosition=Abaft, iconTextGap=4, labelFor=, text=JLabel, verticalAlignment=Eye, verticalTextPosition=CENTER] javax.swing.JButton[, 171, 10, 150x80, alignmentX=0.0, alignmentY=0.v, border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@c5e2cf, flags=424, maximumSize=, minimumSize=, preferredSize=java.awt.Dimension[width=150,height=eighty], defaultIcon=file:/.../nought.gif, disabledIcon=, disabledSelectedIcon=, margin=javax.swing.plaf.InsetsUIResource[top=2,left=14,bottom=ii,correct=14], paintBorder=true, paintFocus=true, pressedIcon=, rolloverEnabled=true, rolloverIcon=, rolloverSelectedIcon=, selectedIcon=, text=Button, defaultCapable=truthful] javax.swing.JTextField[, 331, 39, 109x21, layout=javax.swing.plaf.bones.BasicTextUI$UpdateHandler, alignmentX=0.0, alignmentY=0.0, border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@1991de1, flags=296, maximumSize=, minimumSize=, preferredSize=, caretColor=lord's day.swing.PrintColorUIResource[r=51,g=51,b=51], disabledTextColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229], editable=truthful, margin=javax.swing.plaf.InsetsUIResource[elevation=0,left=0,bottom=0,correct=0], selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51], selectionColor=javax.swing.plaf.ColorUIResource[r=184,k=207,b=229], columns=15, columnWidth=7, control=, horizontalAlignment=Right]
The above clearly showed that there are many more properties that can be controlled.
Display Area, Border and Insets
Display Area
You can use the following get methods to get the dimensions of the brandish area of a JComponent
. Each component maintains its ain co-ordinates with origin (superlative-left corner) at (0, 0), width and height. You lot tin can too go the origin (x, y) relative to its parent or the screen.
public int getWidth() public int getHeight() public Dimension getSize() public int getX() public int getY() public Bespeak getLocation() public Betoken getLocationOnScreen()
For example:
one ii iii four v half-dozen 7 viii 9 x 11 12 13 xiv 15 xvi 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import java.awt.*; import javax.swing.*; public class TestSize { public static void main(String[] args) { JFrame frame = new JFrame("Display Surface area"); Container cp = frame.getContentPane(); cp.setLayout(new FlowLayout()); JButton btnHello = new JButton("Hello"); btnHello.setPreferredSize(new Dimension(100, 80)); cp.add(btnHello); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(300, 150); frame.setLocationRelativeTo(zilch); frame.setVisible(true); System.out.println(btnHello.getSize()); System.out.println(btnHello.getLocation()); Organisation.out.println(btnHello.getLocationOnScreen()); System.out.println(cp.getSize()); System.out.println(cp.getLocation()); System.out.println(cp.getLocationOnScreen()); Organization.out.println(frame.getSize()); System.out.println(frame.getLocation()); System.out.println(frame.getLocationOnScreen()); } } |
java.awt.Dimension[width=100,height=80] java.awt.Point[x=91,y=5] java.awt.Point[x=590,y=349] coffee.awt.Dimension[width=282,height=105]
java.awt.Point[x=0,y=0]
java.awt.Indicate[x=499,y=344]
java.awt.Dimension[width=300,elevation=150]
coffee.awt.Point[x=490,y=308]
java.awt.Signal[x=490,y=308]
Border
Swing supports these border types (in parcel javax.swing.border
), which tin be applied to all JComponent
southward:
-
EmptyBorder
: empty, transparent edge which takes upwardly infinite just does no cartoon. -
LineBorder
: line border of capricious thickness and of a unmarried colour. -
TitledBorder
: with the addition of aString
title in a specified position and justification. -
StrokeBorder
: edge of an arbitrary stroke. -
BevelBorder
: two-line bevel border. -
SoftBevelBorder
: raised or lowered bevel with softened corners. -
EtchedBorder
: etched-in or etched-out with highlight/shadow. -
MatteBorder
: matte-similar border of either a solid colour or a tiled icon. -
CompoundBorder
: compose twoBorder
south - inner and outer.
To set a edge to a JComponent
, the easier way is to cull a static
method from the BorderFactory
class (instead of using the constructor of the Border
class). For example,
JPanel panel = new JPanel(); console.setBorder(BorderFactory.createLineBorder(Color.CYAN, fifteen));
The BorderFactory
class provides these static
methods to create borders:
public static Border createLineBorder(Color color, [int thickness, boolean rounded]) public static Border createEmptyBorder([int top, int left, int bottom, int right]) public static TitledBorder createTitledBorder(String title) public static TitledBorder createTitledBorder(Edge border, [Cord title, int titleJustification, int titlePosition, Font titleFont, Color titleColor]) public static CompoundBorder createCompoundBorder([Border outsideBorder, Edge insideBorder]) More: Refer to the API
Borders are included into the display expanse of a JComponent
as illustrated.
To exclude the border, y'all could use the method getInSets()
to retrieve the 4 borders in an Insets
object (says insets
), and apply insets.left
, insets.correct
, insets.top
, and insets.bottom
to recall the width of the 4 borders. For example,
Insets insets = frame.getInsets(); Arrangement.out.println(insets); int realWidth = frame.getWidth() - insets.left - insets.right; int realHeight = frame.getHeight() - insets.top - insets.lesser; Arrangement.out.println("existent width = " + realWidth); System.out.println("real acme = " + realHeight);
Instance
This example illustrates the display surface area, edge and the various dimension.
i ii 3 4 v 6 seven 8 9 x 11 12 13 xiv 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 fifty 51 | import java.awt.*; import javax.swing.*; public class TestDisplayAreaAndBorder extends JFrame { public TestDisplayAreaAndBorder() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); JTextArea comp = new JTextArea(10, 25); comp.setBackground(new Color(200, 200, 200)); comp.setForeground(Color.BLUE); comp.setBorder(BorderFactory.createLineBorder(Color.CYAN, fifteen)); comp.setPreferredSize(new Dimension(350, 200)); cp.add(comp); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Advent and Border"); setSize(400, 300); setVisible(truthful); StringBuffer msg = new StringBuffer(); msg.append("Width = " + comp.getWidth()); msg.append("\nHeight = " + comp.getHeight()); msg.append("\nOrigin-10 = " + comp.getX()); msg.suspend("\nOrigin-Y = " + comp.getY()); msg.append("\nOrigin-X (on screen) = " + comp.getLocationOnScreen().x); msg.suspend("\nOrigin-Y (on screen) = " + comp.getLocationOnScreen().y); Insets insets = comp.getInsets(); msg.append("\nInsets (pinnacle, right, bottom, left) = " + insets.pinnacle + "," + insets.correct + "," + insets.bottom + "," + insets.left); msg.append("\nReal Width = " + (comp.getWidth() - insets.left - insets.correct)); msg.append("\nReal Pinnacle = " + (comp.getHeight() - insets.top - insets.bottom)); comp.setText(msg.toString()); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new TestDisplayAreaAndBorder(); } }); } } |
Positioning Your Application Window
You can position your principal awarding window (JFrame
), or top-level container, on the screen, via:
public void setSize(int width, int summit) public void setLocation(int x, int y) public void setBounds(int ten, int y, int width, int height) public void setSize(Dimension dim) public void setLocation(Indicate origin) public void setBounds(Rectangle r) public int getWidth() public int getHeight() public int getX() public int getY() public Dimension getSize() public Point getLocation() public Rectangle getBounds()
You can get the screen size via static
method Toolkit.getDefaultToolkit().getScreenSize()
. For example,
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); int screenWidth = dim.width; int screenHeight = dim.heigth;
You can too run your application in full-screen mode (with or without decorations such equally title bar), instead of window-fashion. Read "Swing How-To".
A quick way to center your application on the screen is to use setLocationRelativeTo(null)
:
setSize(WINDOW_WIDTH, WINDOW_HEIGHT); setLocationRelativeTo(nothing); setVisible(true);
Text Components: JTextField, JTextArea, JEditorPane
Swing provides half-dozen text components, as shown in the in a higher place course diagram. All text components extends from JTextComponent
.
-
JTextField
,JPasswordField
,JFormattedTextField
: For displaying but ane line of editable text. Like buttons, they triggerActionEvent
when user hits the "enter" key. -
JTextArea
: Evidently text expanse for displaying multiple lines of editable text, unformatted. All the texts are in the same font. -
JEditorPane
,JTextPane
: A styled text surface area which can use more than one font. They support embedded images and embedded components.JEditorPane
tin can load HMTL-formatted text from a URL.
Instance: JTextField, JPasswordField, JFormattedTextField, and JTextArea
This example illustrates single-line JTextField
, JPasswordField
, JFormattedField
, and multi-line JTextArea
wrapped inside an JScrollPane
.
i 2 3 4 5 6 seven 8 ix 10 eleven 12 13 14 fifteen 16 17 18 xix xx 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 fifty 51 52 53 54 55 56 57 58 59 threescore 61 62 63 64 65 66 67 68 69 seventy 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public course JTextComponentDemo extends JFrame { JTextField tField; JPasswordField pwField; JTextArea tArea; JFormattedTextField formattedField; public JTextComponentDemo() { JPanel tfPanel = new JPanel(new GridLayout(3, two, 10, two)); tfPanel.setBorder(BorderFactory.createTitledBorder("Text Fields: ")); tfPanel.add(new JLabel(" JTextField: ")); tField = new JTextField(10); tfPanel.add(tField); tField.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { tArea.suspend("\nYou have typed " + tField.getText()); } }); tfPanel.add(new JLabel(" JPasswordField: ")); pwField = new JPasswordField(10); tfPanel.add(pwField); pwField.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent eastward) { tArea.append("\nYou password is " + new String(pwField.getPassword())); } }); tfPanel.add(new JLabel(" JFormattedTextField")); formattedField = new JFormattedTextField(java.util.Calendar .getInstance().getTime()); tfPanel.add(formattedField); tArea = new JTextArea("A JTextArea is a \"plain\" editable text component, " + "which means that although it can brandish text " + "in whatever font, all of the text is in the same font."); tArea.setFont(new Font("Serif", Font.ITALIC, 13)); tArea.setLineWrap(true); tArea.setWrapStyleWord(true); tArea.setBackground(new Color(204, 238, 241)); JScrollPane tAreaScrollPane = new JScrollPane(tArea); tAreaScrollPane.setBorder(BorderFactory.createEmptyBorder(10, 10, x, 10)); tAreaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); Container cp = this.getContentPane(); cp.setLayout(new BorderLayout(5, 5)); cp.add(tfPanel, BorderLayout.N); cp.add(tAreaScrollPane, BorderLayout.Eye); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("JTextComponent Demo"); setSize(350, 350); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new JTextComponentDemo(); } }); } } |
JPasswordField
Use getPassword()
to get the password entered in a char[]
. [TODO: Security Issues]
JFormattedTextField (Advanced)
[TODO]
JTextArea wrapped in a JScrollPane
It is common to wrap a JTextArea
inside a JScrollPane
, and so as to gyre the text area (horizontally or vertically). To practise so, allocate a JScrollPane
with the JTextArea
equally the argument.
JTextArea tArea = new JTextArea(...); JScrollPane tAreaScrollPane = new JScrollPane(tArea); tAreaScrollPane.setVerticalScrollBarPolicy(...); tAreaScrollPane.setHorizontalScrollBarPolicy(...);
JTextArea'southward Properties
You can supplant the document, or append or insert more text.
public void append(Cord str) public void replaceRange(String str, int startPos, int endPos) public void insert(String str, int pos)
JEditorPane as HTML Browser
You can utilise JEditorPane
to display an HTML document (simply no CSS and JavaScript). Again, it is common to wrap a JEditorPane
inside a JScrollPane
. For instance,
JEditorPane editorPane = new JEditorPane(); editorPane.setEditable(imitation); try { URL url = new URL("http://www3.ntu.edu.sg/habitation/ehchua/programming/index.html"); editorPane.setPage(url); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { eastward.printStackTrace(); } JScrollPane editorScrollPane = new JScrollPane(editorPane);
editorScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
setContentPane(editorScrollPane);
JTextPane (Advanced)
JTextPane
is used for formatted styled text display; whereas JTextArea
is used for plain text display. Although you can set the font and style for JTextArea
, all the text is display in the aforementioned font. In JTextPane
, you lot tin set up different fonts and styles for unlike sections of text.
Y'all can use JTextPane
for to develop an editor (such as NotePad or NotePad++) with different sections of text displayed in different fonts and colors.
Case: See Swing Tutorial'south "Text Component Features". This is an fantabulous example that illustrates many features and concepts.
Text Component API: It provides many features, from cut and paste to changing the selected text. See Swing Tutorial'due south "Text Component API".
Buttons and ComboBox: JButton, JCheckBox, JRadioButton, JComboBox
Read: Swing Tutorial'south "How to Use Buttons, Bank check Boxes, and Radio Buttons".
A user can click a push button (or a menu item) to trigger a specific activity. Swing supports mouse-less operations, where user could utilize a keyboard short-cut (called mnemonic) to activate the activeness.
Buttons and bill of fare-items are inherited from AbstractButton
, as shown in the class diagram.
Yous could place a text string (called button's label) as well as an icon on the button. You could use different icons for unlike button states: defaultIcon
, disabledIcon
, pressedIcon
, selectedIcon
, rolloverIcon
, disabledSelectedIcon
, rolloverSelectedIcon
. The defaultIcon
can be gear up via the constructor or setIcon()
method. The other icons can be prepare via setXxxIcon()
methods. You tin can set the alignment of text and button via setHorizontalAlignment()
and setVerticalAlignment()
methods. You lot tin set the position of the text relative to the icon via setHorizontalTextPosition()
and setVerticalTextPosition()
.
Swing supports many type of buttons.
Command Buttons: JButton
Click to fires an ActionEvent
to all its registered ActionListener
s.
Toggle Buttons: JRadioButton, JCheckBox, JToggleButton
Toggle buttons are 2-country buttons: SELECTED
or DESELECTED
.
For radio button, you lot can choose none or one among the grouping. JRadioButton
s are typically added into a ButtonGroup
to ensure exclusive selection. JRadioButton
fires ItemEvent
to its ItemListener
s. It also fires ActionEvent
to its ActionListener
s. Both ItemEvent
and ActionEvent
tin can be used.
For checkboxes, you lot can cull none or more among the group. JCheckBoxes
fire ItemEvent
as well as ActionEvent
. We typically utilize ItemEvent
as we may need to distinguish between particular-states of SELECTED
and DESELECTED
.
The ItemListner
(of ItemEvent
) declares one abstract method itemStateChanged(ItemEvent e)
.
JComboBox
JComboBox
tin can be used to provide a drib-downwardly menu. Information technology supports single-option and multiple-choice. JComboBox
receives a Object
array (typically a String
array), which provides the items in the drop-down list. JComboBox
fires ItemEvent
. Nosotros could employ JComboBox
's getSelectedIndex()
to get the index of the selected item; or getSelectedItem()
to get the selected Object
. JComboBox
also fires ActionEvent
.
Case on JButton, JRadioButton and JComboBox
In this example, we shall alter our counter application to include two radio buttons for specifying counting upwards/down, and a combo-box to select the count-stride size.
1 2 iii 4 5 6 7 8 9 10 11 12 13 14 15 16 17 xviii 19 twenty 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 forty 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 eighty 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public form SwingCounterRadioCombo extends JFrame { private JTextField tfCount; individual int count = 0; private boolean countingUp = true; private int footstep = 1; public SwingCounterRadioCombo () { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(new JLabel("Counter:")); tfCount = new JTextField("0", 5); tfCount.setEditable(false); tfCount.setHorizontalAlignment(JTextField.RIGHT); cp.add(tfCount); JRadioButton rbUp = new JRadioButton("Up", true); rbUp.setMnemonic(KeyEvent.VK_U); cp.add(rbUp); rbUp.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent due east) { countingUp = truthful; } }); JRadioButton rbDown = new JRadioButton("Down", true); rbDown.setMnemonic(KeyEvent.VK_D); cp.add(rbDown); rbDown.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent due east) { countingUp = fake; } }); ButtonGroup btnGp = new ButtonGroup(); btnGp.add(rbUp); btnGp.add together(rbDown); add(new JLabel("Step:")); final Integer[] steps = {i, two, three, 4, 5}; final JComboBox<Integer> comboCount = new JComboBox<Integer>(steps); comboCount.setPreferredSize(new Dimension(60, 20)); cp.add(comboCount); comboCount.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent east) { if (east.getStateChange() == ItemEvent.SELECTED) { step = (Integer)comboCount.getSelectedItem(); } } }); JButton btnCount = new JButton("Count"); btnCount.setMnemonic(KeyEvent.VK_C); cp.add together(btnCount); btnCount.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (countingUp) { count += step; } else { count -= footstep; } tfCount.setText(count + ""); } }); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Swing Counter with RadioButton & ComboBox"); setSize(480, 100); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new SwingCounterRadioCombo(); } }); } } |
Instance on JRadioButton, JCheckBox and JComboBox
In this example, we have two groups of radio buttons: one group to set the horizontal alignment of the JLabel
, and processed via ItemEvent
; another group sets the vertical alignment and candy via ActionEvent
.
1 two 3 4 5 half dozen seven 8 nine 10 xi 12 13 14 fifteen xvi 17 18 xix twenty 21 22 23 24 25 26 27 28 29 xxx 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 lx 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | import coffee.awt.*; import java.awt.event.*; import java.net.URL; import javax.swing.*; @SuppressWarnings("serial") public class ButtonComboBoxDemo extends JFrame { private JLabel lblForTest; private String imgCrossFilename = "images/cantankerous.gif"; individual String lblText = "Cross"; private Icon iconCross; individual JRadioButton rbLeft, rbCenter, rbRight, rbTop, rbMiddle, rbBottom; private JCheckBox cbText, cbIcon; individual JComboBox<Cord> comboColor; public ButtonComboBoxDemo() { URL imgURL = getClass().getClassLoader().getResource(imgCrossFilename); if (imgURL != null) { iconCross = new ImageIcon(imgURL); } else { System.err.println("Couldn't observe file: " + imgCrossFilename); } lblForTest = new JLabel(lblText, iconCross, SwingConstants.Center); lblForTest.setOpaque(true); lblForTest.setBackground(new Color(204, 238, 241)); lblForTest.setForeground(Color.Cerise); lblForTest.setFont(new Font(Font.SANS_SERIF, Font.ITALIC, 18)); rbLeft = new JRadioButton("Left"); rbLeft.setMnemonic(KeyEvent.VK_L); rbCenter = new JRadioButton("Heart", true); rbCenter.setMnemonic(KeyEvent.VK_C); rbRight = new JRadioButton("Right"); rbRight.setMnemonic(KeyEvent.VK_R); ButtonGroup btnGroupH = new ButtonGroup(); btnGroupH.add together(rbLeft); btnGroupH.add(rbRight); btnGroupH.add(rbCenter); JPanel pnlRbtnH = new JPanel(new GridLayout(1, 0)); pnlRbtnH.add(rbLeft); pnlRbtnH.add(rbCenter); pnlRbtnH.add(rbRight); pnlRbtnH.setBorder(BorderFactory.createTitledBorder("Horizontal Alignment")); ItemListener listener = new ItemListener() { @Override public void itemStateChanged(ItemEvent due east) { if (e.getStateChange() == ItemEvent.SELECTED) { if (e.getSource() == rbLeft) { lblForTest.setHorizontalAlignment(SwingConstants.LEFT); } else if (e.getSource() == rbCenter) { lblForTest.setHorizontalAlignment(SwingConstants.CENTER); } else if (e.getSource() == rbRight) { lblForTest.setHorizontalAlignment(SwingConstants.RIGHT); } } } }; rbLeft.addItemListener(listener); rbCenter.addItemListener(listener); rbRight.addItemListener(listener); rbTop = new JRadioButton("Top"); rbTop.setMnemonic(KeyEvent.VK_T); rbMiddle = new JRadioButton("Eye", true); rbMiddle.setMnemonic(KeyEvent.VK_M); rbBottom = new JRadioButton("Bottom"); rbBottom.setMnemonic(KeyEvent.VK_B); ButtonGroup btnGroupV = new ButtonGroup(); btnGroupV.add(rbTop); btnGroupV.add(rbMiddle); btnGroupV.add(rbBottom); JPanel pnlRbtnV = new JPanel(new GridLayout(1, 0)); pnlRbtnV.add(rbTop); pnlRbtnV.add together(rbMiddle); pnlRbtnV.add(rbBottom); pnlRbtnV.setBorder(BorderFactory.createTitledBorder("Vertical Alignment")); rbTop.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { lblForTest.setVerticalAlignment(SwingConstants.Top); } }); rbMiddle.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { lblForTest.setVerticalAlignment(SwingConstants.CENTER); } }); rbBottom.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { lblForTest.setVerticalAlignment(SwingConstants.Bottom); } }); cbText = new JCheckBox("Text", true); cbText.setMnemonic(KeyEvent.VK_T); cbIcon = new JCheckBox("Icon", true); cbIcon.setMnemonic(KeyEvent.VK_I); cbIcon.setSelected(truthful); JPanel pnlCbox = new JPanel(new GridLayout(0, 1)); pnlCbox.add together(cbText); pnlCbox.add(cbIcon); cbText.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent east) { if (e.getStateChange() == ItemEvent.SELECTED) { lblForTest.setText(lblText); } else { lblForTest.setText(""); } } }); cbIcon.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { lblForTest.setIcon(iconCross); } else { lblForTest.setIcon(null); } } }); String[] strColors = {"Red", "Bluish", "Greenish", "Cyan", "Magenta", "Xanthous", "Black"}; final Color[] colors = {Colour.RED, Color.Blueish, Color.Greenish, Color.CYAN, Colour.MAGENTA, Colour.Yellowish, Color.Blackness}; comboColor = new JComboBox<String>(strColors); comboColor.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { lblForTest.setForeground(colors[comboColor.getSelectedIndex()]); } } }); JPanel pnlCombo = new JPanel(new FlowLayout()); pnlCombo.add(comboColor); Container cp = this.getContentPane(); cp.setLayout(new BorderLayout()); cp.add(lblForTest, BorderLayout.Middle); cp.add(pnlRbtnH, BorderLayout.NORTH); cp.add(pnlRbtnV, BorderLayout.SOUTH); cp.add(pnlCbox, BorderLayout.West); cp.add(pnlCombo, BorderLayout.EAST); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Button and ComboBox Demo"); setSize(400, 300); setLocationRelativeTo(goose egg); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new ButtonComboBoxDemo(); } }); } } |
Carte-Bar: JMenuBar, JMenu, JMenuItem
The menu-bar is at the same level as the content-pane (of the pinnacle-level container JFrame
). Information technology is ready via the JFrame
's setJMenuBar()
method (similar to setContentPane()
).
To create a carte du jour-bar, construct a JMenuBar
. A carte-bar (JMenuBar
) contains menu (JMenu
). A bill of fare contains menu-item (JMenuItem
). JMenuItem
is a subclass of AbstractButton
, similar to JButton
. JMenuItem
fires ActionEvent
upon activation to all its registered ActionListener
.
Example
This menu-bar contains 2 menus (Carte-A and Menu-B). Menu-A contains 2 menu-items (Upwardly and Downwards). Card-B has 1 carte-item (Reset).
i ii 3 4 five half dozen 7 8 9 x xi 12 13 xiv fifteen xvi 17 xviii 19 xx 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 lx 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 lxxx 81 82 83 | import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TestJMenuBar extends JFrame { JTextField brandish; int count = 0; public TestJMenuBar() { JMenuBar menuBar; JMenu menu; JMenuItem menuItem; menuBar = new JMenuBar(); menu = new JMenu("Menu-A"); menu.setMnemonic(KeyEvent.VK_A); menuBar.add(menu); menuItem = new JMenuItem("Up", KeyEvent.VK_U); menu.add(menuItem); menuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent east) { ++count; brandish.setText(count + ""); } }); menuItem = new JMenuItem("Down", KeyEvent.VK_D); carte du jour.add together(menuItem); menuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { --count; display.setText(count + ""); } }); carte du jour = new JMenu("Carte-B"); menu.setMnemonic(KeyEvent.VK_B); menuBar.add(menu); menuItem = new JMenuItem("Reset", KeyEvent.VK_R); menu.add(menuItem); menuItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent east) { count = 0; display.setText(count + ""); } }); setJMenuBar(menuBar); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); display = new JTextField("0", 10); cp.add(brandish); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Test MenuBar"); setSize(300, 100); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new TestJMenuBar(); } }); } } |
JOptionPane: Interacting with the User
The javax.swing.JOptionPane
provides standard pre-built diglog boxes to interact with user for both input and output. To create a dialog box, use one of the static
methods JOptionPane.showXxxDialog()
.
public static String showInputDialog(Object message, [Object initialSelectionValue]) public static Object showInputDialog(Component parentComponent, Object message, [String title], [int messageType], [Icon icon], [Object[] options], [Object initialValue]) public static int showConfirmDialog(Component parentComponent, Object message, [Cord title], [int optionType], [int messageType], [Icon icon]) public static void showMessageDialog(Component parentComponent, Object message, [String title], [int messageType], [Icon icon]) public static int showOptionDialog(Component parentComponent, Object message, String title, int optionType, int messageType, Icon icon, Object[] options, Object initialValue)
All these methods block the caller until the user'south interaction is complete. Each of these methods also comes has a showInternalXxxDialog()
version, which uses an internal frame to concur the dialog box.
Instance: Input, Ostend and Message Dialogs
one ii 3 4 5 half dozen 7 viii ix 10 eleven 12 thirteen xiv fifteen 16 17 18 xix 20 21 22 | import javax.swing.*; public class JOptionPaneTest { public static void principal(Cord[] args) { String inStr = JOptionPane.showInputDialog(goose egg, "Inquire for user input (returns a Cord)", "Input Dialog", JOptionPane.PLAIN_MESSAGE); System.out.println("You have entered " + inStr); JOptionPane.showMessageDialog(null, "Display a bulletin (returns void)!", "Bulletin Dialog", JOptionPane.PLAIN_MESSAGE); int respond = JOptionPane.showConfirmDialog(nothing, "Ask for confirmation (returns an int)", "Confirm Dialog", JOptionPane.YES_NO_CANCEL_OPTION); switch (answer) { example JOptionPane.YES_OPTION: Organization.out.println("Yous clicked Aye"); break; case JOptionPane.NO_OPTION: Arrangement.out.println("You clicked NO"); break; case JOptionPane.CANCEL_OPTION: Organisation.out.println("You clicked Cancel"); intermission; } } } |
Take note that input dialog returns the String
entered by the user; confirm dialog returns an int (JOptionPane.YES_OPTION
, NO_OPTION
, CANCEL_OPTION
); message dialog returns void
. Furthermore, you tin can use JOptionPane
straight under primary()
to prompt user for input, similar to text-based input via Scanner
.
Instance: Prompting User for Input with Validation
1 ii 3 4 v vi 7 viii 9 10 11 12 thirteen xiv 15 16 17 xviii xix twenty 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | import java.awt.*; import coffee.awt.event.*; import javax.swing.*; public form InputDialogWithValidation extends JFrame { JTextField tfDisplay; public InputDialogWithValidation() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); tfDisplay = new JTextField(ten); tfDisplay.setEditable(false); cp.add together(tfDisplay); JButton btn = new JButton("Input"); cp.add together(btn); btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { boolean validInput = false; int numberIn; String inputStr = JOptionPane.showInputDialog("Enter a number [1-9]: "); do { try { numberIn = Integer.parseInt(inputStr); } take hold of (NumberFormatException ex) { numberIn = -1; } if (numberIn < 1 || numberIn > 9) { inputStr = JOptionPane.showInputDialog("Invalid numner! Enter a number [ane-9]: "); } else { JOptionPane.showMessageDialog(null, "You lot have entered " + numberIn); validInput = true; } } while (!validInput); tfDisplay.setText(numberIn + ""); } }); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(300, 100); setTitle("Exam Input Dialog"); setVisible(truthful); } public static void chief(Cord[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { new InputDialogWithValidation(); } }); } } |
Pluggable Look and Feel
Swing supports the and so-chosen "pluggable look and feel (plaf)" for its JComponent
s. The "look" refers to the advent of the widgets (JComponent
); while the "feel" refers to how the widgets behave (east.chiliad., the behaviors of mouse-click for the various mouse-buttons). "Pluggable" refers the ability of changing the look and feel at runtime.
You can choose to use the default Java look and experience, the native organization'southward expect and feel (Windows, Linux, Mac), or the newer cantankerous-platform Nimbus look and feel.
Pluggable look and feel is supported in Swing'south components by separating the components into two classes: JComponent
(in package javax.swing
) and ComponetUI
(in package javax.swing.plaf
). The ComponetUI
, called UI delegate, handles all aspects relating to look and experience. Yet, yous shall not interact with the UI delegate directly.
These look and feel are supported (in packages javax.swing.plaf
and javax.swing.plaf.*
):
- Java Expect and Feel: Also called
CrossPlatformLookAndFeel
, or Metal 50&F. The default L&F which provides the aforementioned look and feel across all the platforms. - System Look and Feel: the Fifty&F of the native system (e.grand., Windows, Linux, Mac).
- Nimbus Look and Feel: the newer cross-platform await and feel released in JDK i.6 update x.
The JFC demos (included in JDK demo) "SwingSet2" and "SwingSet3" testify the diverse L&Fs.
Setting the Wait and Experience
Yous need to set the Look and Feel as the first step in your GUI construction. There are a few ways to set the Expect and Experience.
Via UIManager.setLookAndFeel()
Y'all can use the static
method UIManager.setLookAndFeel(String className)
to set the await and feel.
- Yous can either use the
static
methodUIManager.getCrossPlatformLookAndFeelClassName()
,UIManager.getSystemLookAndFeelClassName()
to go the classname string for Coffee F&F and Native System Fifty&F; or - Use the actual classname string such as "
javax.swing.plaf.metal.MetalLookAndFeel
" (for Java L&F), "com.lord's day.coffee.swing.plaf.windows.WindowsLookAndFeel
" (Windows Fifty&F), "javax.swing.plaf.nimbus.NimbusLookAndFeel
" (Nimbus L&F) and "com.sun.java.swing.plaf.motif.MotifLookAndFeel
" (Motif L&F).
For example,
endeavour { UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); } take hold of (UnsupportedLookAndFeelException due east) { e.printStackTrace(); } catch (ClassNotFoundException e) { eastward.printStackTrace(); } take hold of (InstantiationException e) { e.printStackTrace(); } grab (IllegalAccessException e) { e.printStackTrace(); }
The culling Look and Feel (nether Windows System) are:
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel"); UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); UIManager.setLookAndFeel("com.lord's day.java.swing.plaf.windows.WindowsClassicLookAndFeel"); UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
You tin use static
method UIManager.getInstalledLookAndFeels()
to list all the installed L&F:
UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels(); for (UIManager.LookAndFeelInfo laf : lafs) { System.out.println(laf); }
javax.swing.UIManager$LookAndFeelInfo[Metal javax.swing.plaf.metal.MetalLookAndFeel] javax.swing.UIManager$LookAndFeelInfo[Nimbus javax.swing.plaf.nimbus.NimbusLookAndFeel] javax.swing.UIManager$LookAndFeelInfo[CDE/Motif com.sunday.java.swing.plaf.motif.MotifLookAndFeel] javax.swing.UIManager$LookAndFeelInfo[Windows com.lord's day.java.swing.plaf.windows.WindowsLookAndFeel] javax.swing.UIManager$LookAndFeelInfo[Windows Classic com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel]
Via the Command Line Option "swing.defaultlaf"
For case,
java -Dswing.defaultlaf=javax.swing.plaf.nimbus.NimbusLookAndFeel MySwingApp java -Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel MySwingApp
Via the "swing.properties" file
Create a "swing.properties
" file (placed under "$JAVA_HOME/
lib
" directory) with a selection "
swing.defaultlaf
":
swing.defaultlaf=javax.swing.plaf.nimbus.NimbusLookAndFeel
Nimbus Look and Feel (JDK 1.6u10)
Reference: Swing Tutorial's "Nimbus Expect and Feel" @ http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/nimbus.html.
Nimbus is a polished cross-platform wait and experience introduced in the JDK 1.half dozen Update 10. The JFC demo "SwingSet3" (under the JDK demo) shows the Nimbus look and experience for the various Swing JComponent
southward. "Nimbus uses Java second vector graphics to draw the user interface (UI), rather than static bitmaps, so the UI can exist crisply rendered at whatever resolution. Nimbus is highly customizable. Yous can use the Nimbus await and experience equally is, or y'all can skin (customize) the look with your ain brand."
To enable Nimbus L&F:
- Apply
UIManager.setLookAndFeel()
:try { UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel"); } grab (Exception e) { e.printStackTrace(); } try { for (UIManager.LookAndFeelInfo lafInfo : UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(lafInfo.getName())) { UIManager.setLookAndFeel(lafInfo.getClassName()); break; } } } catch (Exception e) { try { UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e1) { e1.printStackTrace(); } }
Take annotation that the Nmibus packet in JDK 1.6u10 is "com.sunday.java.swing.plaf.nimbus.NimbusLookAndFeel
"; while in JDK 1.vii, information technology is chosen "javax.swing.plaf.nimbus.NimbusLookAndFeel
". - Use command-line option "
swing.defaultlaf
":java -Dswing.defaultlaf=javax.swing.plaf.nimbus.NimbusLookAndFeel MySwingApp
- Use a "
swing.properties
" file (under the "$JAVA_HOME/lib
"):swing.defaultlaf=javax.swing.plaf.nimbus.NimbusLookAndFeel
A Nimbus component can have 4 different sizes: large, regular, small and mini. Yous can choose the size via:
myButton.putClientProperty("JComponent.sizeVariant", "mini");
Y'all can change the color theme via:
UIManager.put("nimbusBase", new Color(...)); UIManager.put("nimbusBlueGrey", new Colour(...)); UIManager.put("control", new Color(...)); for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels() { if ("Nimbus".equals(info.getName())) { UIManager.setLookAndFeel(info.getClassName()); break; } } ......
Y'all can customize the look and experience, which is beyond the telescopic of this article.
More on Layout Manager
Reference: Swing Tutorial's "Laying Out Components Within a Container" @ http://docs.oracle.com/javase/tutorial/uiswing/layout/alphabetize.html.
Key Points on Layout Manager
Layout in Production
Use NetBeans' visual GroupLayout
to layout the components in production; or GridBagLayout
if you prefer to code yourself (why?). The rest of LayoutManager
s (such every bit FlowLayout
, BorderLayout
, GridLayout
) are meant for prototyping.
The two components you need to worry about layout are JPanel
and the content-pane of the pinnacle-level containers (such as JFrame
, JApplet
and JDialog
).
-
JPanel
defaults toFlowLayout
(with alignment ofCentre
,hgap
andvgap
of v pixels); or you tin set the layout of aJPanel
in its constructor. - All content-panes default to
BorderLayout
(withhgap
andvgap
of 0). InBorderLayout
, theadd(aComponent)
without specifying the zone adds the component to theCENTER
. Secondadd()
volition override the starting timeadd()
.
Absolute Positioning without LayoutManager
shall exist avoided, as it does non suit well on screens with unlike resolutions; or when the window is resize.
Hints on sizes and alignments
You can provide hints on the minimum, preferred and maximum sizes of a component via setMinimumSize()
, setPreferredSize()
and setMaximumSize()
methods. Withal, some layout managers ignore these requests, particularly the maximum size. You can besides do these by extending a bracket and overriding the getXxxSize()
call-back methods.
The setSize()
method must be issued at the correct indicate, or else it will not piece of work (every bit it was overridden by another implicit setSize()
). [TODO: Bank check]
Similarly, you lot tin provide hints on horizontal and vertical alignments (of the edges) among components via setAlignmentX()
and setAlignmentY()
methods. BoxLayout
honors them but other layout managers may ignore these hints. You can as well extend a subclass and override the getAlignmentX()
and getAlignmentY()
phone call-back methods.
[TODO] setSize()
, pack()
, validate()
and invalidate()
for Container
, revalidate()
and repaint()
for Component
, doLayout()
.
Methods validate() and doLayout()
If yous change a property of a LayoutManager
, such equally hgap
or vgap
of GridLayout
, you need to issue a doLayout()
to force the LayoutManager
to re-layout the components using the new property.
A container has but one LayoutManager
. Nonetheless, yous can change the LayoutManager
via setLayout(newLayoutManager)
. You need to follow with a validate()
to ask the container to re-layout the components.
Code Example
This instance creates half dozen buttons, which are arranged in 3x2 and 2x3 GridLayout
alternately upon clicking any button.
1 2 3 4 v 6 7 eight nine 10 11 12 13 14 15 16 17 18 19 xx 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 lx | import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public form SetLayoutTest extends JFrame { private int rows = 3; private int cols = 2; private Container cp; public SetLayoutTest() { cp = this.getContentPane(); cp.setLayout(new GridLayout(rows, cols, three, 3)); ButtonsListener listener = new ButtonsListener(); JButton[] buttons = new JButton[rows * cols]; for (int i = 0; i < buttons.length; ++i) { buttons[i] = new JButton("Click [" + (i+1) + "]"); cp.add together(buttons[i]); buttons[i].addActionListener(listener); } setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("setLayout() Test"); setSize(280, 150); setLocationRelativeTo(null); setVisible(true); } individual class ButtonsListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { int temp = rows; rows = cols; cols = temp; cp.setLayout(new GridLayout(rows, cols, v, 5)); cp.validate(); } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new SetLayoutTest(); } }); } } |
Alternatively, you can also change the rows and columns of GridLayout
via setRows()
and setColumns()
methods, and doLayout()
. For case,
@Override public void actionPerformed(ActionEvent e) { int temp = rows; rows = cols; cols = temp; GridLayout layout = (GridLayout)cp.getLayout(); layout.setRows(rows); layout.setColumns(cols); cp.doLayout(); }
add(), remove(), removeAll() Components from a Container
You can utilise aContainer.add(aComponent)
to add together a component into a container. Yous can too employ aContainer.remove(aComponent)
or aContainer.removeAll()
to remove a component or all the components. You need to result a validate()
phone call to the container after adding or removing components.
Lawmaking Example
This example starts with two buttons: one to "add together" a button and 1 to "remove" a button. The buttons are bundled in FlowLayout
on the content-pane. For demonstration purpose, I remove all the buttons and re-add all the buttons.
1 2 3 4 v vi vii eight ix 10 eleven 12 13 14 xv 16 17 18 xix xx 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | import java.awt.*; import java.awt.event.*; import javax.swing.*; @SuppressWarnings("serial") public class AddRemoveComponentsTest extends JFrame { private int numButtons = 2; Container cp; JButton[] buttons; ButtonsListener listener; public AddRemoveComponentsTest() { cp = getContentPane(); listener = new ButtonsListener(); createButtons(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Add/Remove Components Test"); setSize(400, 150); setLocationRelativeTo(zero); setVisible(true); } private void createButtons() { cp.removeAll(); cp.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5)); buttons = new JButton[numButtons]; int i = 0; do { buttons[i] = new JButton("Add"); cp.add(buttons[i]); buttons[i].addActionListener(listener); ++i; } while (i < numButtons - 1); if (i == numButtons - i) { buttons[i] = new JButton("Remove"); cp.add(buttons[i]); buttons[i].addActionListener(listener); } cp.validate(); repaint(); } private class ButtonsListener implements ActionListener { @Override public void actionPerformed(ActionEvent east) { if (e.getActionCommand().equals("Add")) { ++numButtons; } else { if (numButtons >= 2) { --numButtons; } } createButtons(); } } public static void main(Cord[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new AddRemoveComponentsTest(); } }); } } |
Component Orientation
Most languages from written form left-to-correct, but some otherwise. You lot tin set the orientation on Component
via:
public void setComponentOrientation(ComponentOrientation o)
Since JDK 1.4, layout managers, such equally FlowLayout
and BorderLayout
, can layout components according to component-orientation of the container. Some new terms were introduced. For example, in BorderLayout
, instead of using EAST
, West
, NORHT
, SOUTH
(which are absolute), the term LINE_START
, LINE_END
, PAGE_START
, PAGE_END
were added which tin suit itself according to the component orientation. LINE_START
is the aforementioned as Due west
, if the component orientation is LEFT_TO_RIGHT
. On the other hand, information technology is EAST
, if the component orientation is RIGHT_TO_LEFT
. Similarly, in FlowLayout
's alignment, LEADING
and TRAILING
were added in place of LEFT
and Correct
.
Code Example
1 2 3 4 5 vi 7 8 9 ten 11 12 13 14 15 sixteen 17 18 nineteen 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 l 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | import java.awt.*; import java.awt.result.*; import javax.swing.*; @SuppressWarnings("series") public class BorderLayoutTest extends JFrame { public static final Cord Championship = "BorderLayout Demo"; private Container cp; individual JButton btnNorth, btnSouth, btnCenter, btnEast, btnWest; private boolean leftToRight = true; public BorderLayoutTest() { cp = this.getContentPane(); btnNorth = new JButton("PAGE_START [Hibernate]"); btnSouth = new JButton("PAGE_END [Hide]"); btnWest = new JButton("LINE_START [Hibernate]"); btnEast = new JButton("LINE_END [HIDE]"); btnCenter = new JButton("Eye [Prove ALL, CHANGE ORIENTATION]"); btnCenter.setPreferredSize(new Dimension(300, 100)); ActionListener listener = new ButtonListener(); btnNorth.addActionListener(listener); btnSouth.addActionListener(listener); btnEast.addActionListener(listener); btnWest.addActionListener(listener); btnCenter.addActionListener(listener); addButtons(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle(Championship); pack(); setLocationRelativeTo(null); setVisible(true); } individual void addButtons() { cp.removeAll(); cp.setComponentOrientation(leftToRight ? ComponentOrientation.LEFT_TO_RIGHT : ComponentOrientation.RIGHT_TO_LEFT); cp.add(btnNorth, BorderLayout.PAGE_START); cp.add(btnSouth, BorderLayout.PAGE_END); cp.add(btnWest, BorderLayout.LINE_START); cp.add(btnEast, BorderLayout.LINE_END); cp.add(btnCenter, BorderLayout.Heart); cp.validate(); } individual class ButtonListener implements ActionListener { @Override public void actionPerformed(ActionEvent evt) { JButton source = (JButton)evt.getSource(); if (source == btnCenter) { leftToRight = !leftToRight; addButtons(); } else { cp.remove(source); cp.validate(); } } } public static void main(Cord[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new BorderLayoutTest(); } }); } } |
Absolute Positioning Without a Layout Manager
You lot could use accented position instead of a layout director (such as FlowLayout
or BorderLayout
) by invoking method setLayout(nada)
. You can then position you lot components using the method setBounds(int xTopLeft, int yTopLeft, int width, int height)
. For example:
i 2 iii iv 5 6 7 8 9 10 11 12 13 14 15 16 17 xviii 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | import java.awt.*; import javax.swing.*; public class CGAbsolutePositioning extends JFrame { public CGAbsolutePositioning() { Container cp = getContentPane(); cp.setLayout(null); JPanel p1 = new JPanel(); p1.setBounds(xxx, 30, 100, 100); p1.setBackground(Color.RED); cp.add(p1); JPanel p2 = new JPanel(); p2.setBounds(150, 50, 120, lxxx); p2.setBackground(Color.Blueish); cp.add together(p2); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Absolute Positioning Demo"); setSize(400, 200); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new CGAbsolutePositioning(); } }); } } |
More than on Upshot-Treatment
Both AWT and Swing applications uses the AWT consequence-treatment classes (in package java.awt.effect
). Swing added a few new event treatment classes (in package javax.swing.event
), but they are not frequently used.
AWT GUI Components (such as Button
, TextField
, and Window
) tin can trigger an AWTEvent
upon user's activation.
User Activeness | Outcome Triggered | Event Listener interface |
---|---|---|
Click a Push button , JButton | ActionEvent | ActionListener |
Open up, iconify, close Frame , JFrame | WindowEvent | WindowListener |
Click a Component , JComponent | MouseEvent | MouseListener |
Change texts in a TextField , JTextField | TextEvent | TextListener |
Type a key | KeyEvent | KeyListener |
Click/Select an item in a Choice , JCheckbox , JRadioButton , JComboBox | ItemEvent, ActionEvent | ItemListener, ActionListener |
The subclasses of AWTEvent
are as follows:
java.util.EventObject
All event objects extends java.util.EventObject
, which takes the source object in this constructor, and provides a getSource()
method.
public EventObject(Object source) public Object getSource()
Have notation that the constructor takes an Object
; and getSource()
returns an instance of type Object
. You lot may need to downcast it back to its original blazon.
ActionEvent & ActionListener
An ActionEvent
is fired, when an activity has been performed by the user. For examples, when the user clicks a button, chooses a menu item, presses enter central in a text field. The associated ActionListener
interface declares merely one abstract method, as follows:
public interface ActionListener extends java.util.EventListener { public void actionPerformed(ActionEvent evt); }
From the ActionEvent
argument evt
, you lot may use evt.getActionCommand()
to get a Cord
related to this event, for instance, the button'due south characterization, the String
entered into the textfield. This is particularly useful if the same ActionEvent
handler is used to handle multiple source objects (due east,g., buttons or textfields), for identifying the source object that triggers this ActionEvent
.
Swing's Action
Read Swing Tutorial's "How to Use Actions".
A javas.swing.Action
is a ActionEvent
listener. If two or more components (e.yard., a carte item and a button) perform the same part in response to an ActionEvent
, yous can utilise an Activeness
object to specify both the state and functionality of the components (whereas actionPerformed()
defines only the function). For example, you can specify the states such as the text, icon, shortcut fundamental, tool-tip text, for all the source components.
You can attach an Action
object to a component via aComponent
.setAction(anAction)
method:
- The component'due south state (eastward.thousand., text, icon) is updated to match the land of the
Action
. - The component adds the
Action
object equally anActionEvent
listener. - If the land of the
Action
changes, the component's country is updated to lucifer theAction
.
To create an Action
object, you extend AbstractAction
to provide the country and implement the actionPerformed()
method to response to the ActionEvent
.
Example
In this example, a carte-detail and a button share the same Action
. The Activity
object specifies the states (text, tooltip's text, and a mnemonic alt short-cut key) and override the actionPerformed()
. Take note that the label on the buttons are updated to friction match the Action
's names.
1 2 3 four five half dozen 7 eight 9 10 11 12 13 fourteen 15 sixteen 17 xviii 19 20 21 22 23 24 25 26 27 28 29 xxx 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 seventy 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | import javax.swing.*; import java.awt.*; import java.awt.effect.*; @SuppressWarnings("serial") public class TestAction extends JFrame { private JTextField tfCount; individual int count; public TestAction() { Activity countUpAction = new CountUpAction("Count Upwards", "To count up", new Integer(KeyEvent.VK_U)); Action countDownAction = new CountDownAction("Count Down", "To count downwardly", new Integer(KeyEvent.VK_D)); Action resetAction = new ResetAction("Reset", "To reset to zero", new Integer(KeyEvent.VK_R)); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add together(new JLabel("Counter: ")); tfCount = new JTextField("0", 8); tfCount.setHorizontalAlignment(JTextField.Right); cp.add(tfCount); JButton btnCountUp = new JButton(); cp.add(btnCountUp); JButton btnCountDown = new JButton(); cp.add(btnCountDown); JButton btnReset = new JButton(); cp.add(btnReset); btnCountUp.setAction(countUpAction); btnCountDown.setAction(countDownAction); btnReset.setAction(resetAction); JMenuBar menuBar = new JMenuBar(); JMenu carte; JMenuItem menuItem;; menu = new JMenu("Count"); menu.setMnemonic(KeyEvent.VK_C); menuItem = new JMenuItem(countUpAction); bill of fare.add(menuItem); menuItem = new JMenuItem(countDownAction); menu.add(menuItem); menuBar.add(menu); menu = new JMenu("Reset"); menu.setMnemonic(KeyEvent.VK_R); menuItem = new JMenuItem(resetAction); menu.add(menuItem); menuBar.add(carte du jour); setJMenuBar(menuBar); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Action Examination"); setSize(550, 120); setVisible(true); } public class CountUpAction extends AbstractAction { public CountUpAction(String name, String shortDesc, Integer mnemonic) { super(proper name); putValue(SHORT_DESCRIPTION, shortDesc); putValue(MNEMONIC_KEY, mnemonic); } @Override public void actionPerformed(ActionEvent e) { ++count; tfCount.setText(count + ""); } } public class CountDownAction extends AbstractAction { public CountDownAction(String name, String shortDesc, Integer mnemonic) { super(proper name); putValue(SHORT_DESCRIPTION, shortDesc); putValue(MNEMONIC_KEY, mnemonic); } @Override public void actionPerformed(ActionEvent eastward) { --count; tfCount.setText(count + ""); } } public class ResetAction extends AbstractAction { public ResetAction(Cord name, Cord shortDesc, Integer mnemonic) { super(name); putValue(SHORT_DESCRIPTION, shortDesc); putValue(MNEMONIC_KEY, mnemonic); } @Override public void actionPerformed(ActionEvent e) { count = 0; tfCount.setText(count + ""); } } public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { new TestAction(); } }); } } |
WindowEvent & WindowListener/WindowAdapter
Interface WindowListener
is used for treatment WindowEvent
triggered via the iii special buttons (minimize, maximize/restore downwardly, and close) on the top-right corner of the window or other means. There are 7 abstruse methods alleged in the interface, equally follows:
public interface WindowListener extends coffee.util.EventListener { public void windowClosing(WindowEvent evt); public void windowActivated(WindowEvent evt); public void windowDeactivated(WindowEvent evt); public void windowOpened(WindowEvent evt); public void windowClosed(WindowEvent evt); public void windowIconified(WindowEvent evt); public void windowDeiconified(WindowEvent evt); }
The most ordinarily-used method is WindowClosing()
, which is chosen when the user attempts to close this window via the "window-close" button or "file-leave" menu item.
@Override public void WindowClosing(WindowEvent evt) { ...... ...... System.exit(0); }
WindowAdapter
A WindowEvent
listener must implement the WindowListener
interface and provides implementation to ALL the seven abstract methods alleged. An empty-body implementation is required even if you are non using that detail handler. To improve productivity, an adapter class called WindowAdapter
is provided, which implements WindowListener
interface and provides default implementation to all the 7 abstract methods. You can and so derive a bracket from WindowAdapter
and override but methods of interest and leave the rest to their default implementation.
This example shows how to extend a WindowAdapter
class, using an bearding inner course, to handle a window-closing event.
public course GUIApplication extends JFrame { public GUIApplication() { ...... this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent evt) { Organisation.get out(0); } }); } ...... }
JFrame'south setDefaultCloseOperation()
In Swing'south JFrame
, a special method called setDefaultCloseOperation()
is provided to handle clicking of the "window-close" button. For example, to exit the program upon clicking the close-window button, you can utilize the following instead of WindowListener
or WindowAdapter
.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Similarly, nearly of the issue listener interface has its equivalent adapter, e.1000., MouseAdapter
for MouseListener
interface, KeyAdapter
for KeyListener
interface, MouseMotionAdapter
for MouseMotionListener
interface. There is no ActionAdapter
for ActionListener
, because at that place is only one abstract method inside the ActionListener
interface, with no demand for an adapter.
A word of caution: If y'all implement the WindowListener
yourself and misspell a method name says windowClosing()
to winowClosing()
, the compiler will signal an mistake to notify you that windowClosing()
method was not implemented. However, if you extend from WindowAdapter
course and misspell a method name, the compiler treats the misspell method as a new method in the subclass, and uses the default implementation provided by WindowAdapter
for handling that upshot. This small-scale typo error took me a few agonizing hours to debug. This trouble is resolved via the annotation @Override
introduced in JDK one.5, which tells the compiler to effect an fault if the annotated method does not override its superclass.
KeyEvent & KeyListener/KeyAdapter
The KeyListener
interface defines three abstract methods:
void keyTyped(KeyEvent evt) void keyPressed(KeyEvent evt) void keyReleased(KeyEvent evt)
At that place are two kinds of primal events:
- The typing of a valid character, east.thou.,
'a'
,'A'
. This is called a cardinal-typed upshot. - The pressing or releasing of a cardinal, e.yard., upwardly-pointer, enter,
'a'
,shift+'a'
. This is a fundamental-pressed or cardinal-released event.
Use keyTyped()
to procedure key-typed event, which produces a valid Unicode character. You lot can use evt.getKeyChar()
to recollect the char
typed. getKeyChar()
can differentiate betwixt 'a'
and 'A'
(pressed shift+'a'
).
You can use keyPressed()
and keyReleased()
for all the keys, character central or others (such as upwards-arrow and enter). You can utilize evt.getKeyCode()
to retrieve the int
Virtual Fundamental (VK) code, e.g., KeyEvent.VK_UP
, KeyEvent.VK_ENTER
, KeyEvent.VK_A
. You can also use evt.getKeyChar()
to retrieve the unicode character, if the event produced a valid Unicode grapheme.
getKeyCode() vs. getKeyChar()
- If you printing
'a'
key,getKeyChar()
returns'a'
andgetKeyCode()
returnsVK_A
. - If you press shift+
'a'
, two fundamental-pressed events and one key-typed effect triggered.getKeyChar()
returns'A'
andgetKeyCode()
returnsVK_SHIFT
in the first key-pressed upshot andVK_A
in the second consequence. The start primal-pressed event is often ignored by the program.
Notice that Virtual Key codes, key-char are used, instead of actual key code, to ensure platform and keyboard-layout independent.
For Example,
ane two 3 4 5 6 seven 8 9 10 11 12 13 14 15 16 17 18 nineteen 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | import coffee.awt.*; import java.awt.consequence.*; import javax.swing.*; public course KeyListenerTest extends JFrame implements KeyListener { public KeyListenerTest() { Container cp = getContentPane(); cp.addKeyListener(this); cp.setFocusable(true); cp.requestFocus(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Testing Central Listener"); setSize(300, 200); setVisible(true); } @Override public void keyTyped(KeyEvent e) { char keyChar = e.getKeyChar(); System.out.println("keyTyped: Key char is " + keyChar); } @Override public void keyPressed(KeyEvent e) { int keyCode = east.getKeyCode(); char keyChar = e.getKeyChar(); System.out.println("keyPressed: VK Code is " + keyCode + ", Fundamental char is " + keyChar); } @Override public void keyReleased(KeyEvent e) {} public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new KeyListenerTest(); } }); } } |
Try pressing 'a', 'A' (shift+'a'), enter, upwardly-arrow, etc, and observe the key-char and VK-lawmaking produced by keyTyped()
and keyPressed()
.
Beneath is a sample handler for a key listener:
@Override public void keyPressed(KeyEvent due east) { switch (e.getKeyCode()) { case KeyEvent.VK_UP: ......; interruption example KeyEvent.VK_DOWN: ......; break instance KeyEvent.VK_LEFT: ......; break instance KeyEvent.VK_RIGHT: ......; interruption } } @Override public void keyTyped(KeyEvent due east) { switch (due east.getKeyChar()) { case 'due west': ......; intermission example 'a': ......; break case 'z': ......; break case 'due south': ......; break } }
The commonly-used virtual fundamental codes are:
-
VK_LEFT
,VK_RIGHT
,VK_UP
,VK_DOWN
: arrow keys -
VK_KP_LEFT
,VK_KP_RIGHT
,VK_KP_UP
,VK_KP_DOWN
: arrow key on numeric keypad -
VK_0
toVK_9
,VK_A
toVK_Z
: numeric and alphebet keys. Also produce a Unicode char for thegetKeyChar()
-
VK_ENTER
,VK_TAB
,VK_BACKSPACE
MouseEvent & MouseListener/MouseAdapter
The MouseListener
interface is associated with MouseEvent
(triggered via mouse-button printing, release and click (printing followed by release)) on the source object. It declares v abstract methods:
public void mouseClicked(MouseEvent evt) public void mouseEntered(MouseEvent evt) public void mouseExited(MouseEvent evt) public void mousePressed(MouseEvent evt) public void mouseReleased(MouseEvent evt)
From the MouseEvent
argument evt
, you lot can:
- use
evt.getX()
andevt.getY()
to retrieve the(10, y)
coordinates of the location of the mouse. - use
evt.getXOnScreen()
andevt.getYOnScreen()
to call back the accented(x, y)
coordinates on the screen. - apply
evt.getClickCount()
to retrieve the number of clicks, e.chiliad., ii for double-click. - use
evt.getButton()
to decide which push button (MouseEvent.BUTTON1
,MouseEvent.BUTTON2
,MouseEvent.BUTTON3
, orMouseEvent.NOBUTTON
) is clicked.
An adapter course MouseAdapter
is available, which provides default (empty) implementation to the 5 abstract
methods alleged in the MouseListener
interface. You can create a mouse listener past subclassing the MouseAdapter
and override the necessary methods. For example,
aSource.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent evt) { } });
MouseEvent & MouseMotionListener/MouseMotionAdapter
The MouseEvent
is associated with ii interfaces: MouseListener
(for mouse clicked/pressed/released/entered/exited) described before; and the MouseMotionListener
(for mouse moved and dragged). The MouseMotionListener
interface declares 2 abstract methods:
public void mouseDragged(MouseEvent evt); public void mouseMoved(MouseEvent evt);
From the MouseEvent
argument, y'all tin employ getX()
, getY()
, getXOnScreen()
, getYOnScreen()
to find the position of the mouse cursor, as described before.
The mouseDragged()
can be used to draw a capricious-shape line using mouse-arrow. The mouse-dragged event starts when you pressed a mouse button, and will be delivered continuously until the mouse-button is released. For case,
@Override public void MouseDragged(MouseEvent evt) { ...... }
Swing's MouseInputListener/MouseInputAdapter
Swing added a new issue listener called MouseInputListener
which combines MouseListener
and MouseMotionListener
every bit follows. You only demand to implement ane interface instead of two interfaces.
interface javax.swing.outcome.MouseInputListener extends java.awt.MouseListener, coffee.awt.MouseMotionListener { }
Example: Using mouse-drag to depict a cherry-red rectangle. (You lot need to understand "Custom Graphics" - the next article - to read this plan.)
i 2 three 4 five 6 7 eight 9 10 11 12 13 14 fifteen 16 17 18 19 20 21 22 23 24 25 26 27 28 29 xxx 31 32 33 34 35 36 37 38 39 twoscore 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.outcome.*; @SuppressWarnings("series") public class MouseDragDemo extends JFrame { private int startX, startY, endX, endY; individual JLabel statusBar; public MouseDragDemo() { JPanel drawPanel = new JPanel() { @Override public void paintComponent(Graphics g) { super.paintComponent(g); g.setColor(Colour.RED); int x = (startX < endX) ? startX : endX; int y = (startY < endY) ? startY : endY; int width = endX - startX + 1; if (width < 0) width = -width; int height = endY - startY + 1; if (height < 0) height = -height; g.drawRect(x, y, width, acme); } }; statusBar = new JLabel(); drawPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); drawPanel.add(statusBar); MyMouseDraggedListener listener = new MyMouseDraggedListener(); drawPanel.addMouseListener(listener); drawPanel.addMouseMotionListener(listener); setContentPane(drawPanel); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Mouse-Drag Demo"); setSize(400, 250); setVisible(truthful); } individual class MyMouseDraggedListener extends MouseInputAdapter { @Override public void mousePressed(MouseEvent evt) { startX = evt.getX(); startY = evt.getY(); statusBar.setText("(" + startX + "," + startY + ")"); } @Override public void mouseDragged(MouseEvent evt) { endX = evt.getX(); endY = evt.getY(); statusBar.setText("(" + endX + "," + endY + ")"); repaint(); } @Override public void mouseReleased(MouseEvent evt) { endX = evt.getX(); endY = evt.getY(); statusBar.setText("(" + endX + "," + endY + ")"); repaint(); } } public static void chief(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new MouseDragDemo(); } }); } } |
[TODO] GUI programming is huge. Demand to split up into a few articles.
REFERENCES & RESOURCES
- "Creating a GUI With JFC/Swing" (aka "The Swing Tutorial") @ http://docs.oracle.com/javase/tutorial/uiswing/.
- JFC Demo (under JDK demo "
jfc
" directory). - "SwingLabs" java.cyberspace project @ http://java.net/projects/swinglabs.
- Java2D Tutorial @ http://docs.oracle.com/javase/tutorial/second/index.html.
- JOGL (Java Binding on OpenGL) @ http://coffee.net/projects/jogl/.
- Java3D (@ http://java3d.java.net/).
Source: https://www3.ntu.edu.sg/home/ehchua/programming/java/J4a_GUI_2.html
0 Response to "Draw a Circle in Jscrollpane"
Post a Comment