Java Guiavanzada PDF
Java Guiavanzada PDF
public void init() { // called when page is loaded into browser codebase = getCodeBase(); img = getImage( codebase, "tux.jpg"); } public void paint(Graphics g) { // called every time applet needs redrawing g.drawImage(img, 0, 0, this); } public void start() { // called every time page containing applet is displayed } public void stop() { // called every time page containing applet is overwritten } public void destroy() { // called when applet removed from browser. } } 1
The program is in the le ImageApplet0.java and the image in tux.jpg. This applet displays an image that looks like this when executed by the browser refox:
The le that must be viewed by the browser so that the applet is loaded and started is called ImageApplet0.html: <html> <body> <h1> Here is Tux </h1> <p> <applet code="ImageApplet0.class" width="300" height="350"> </applet> </p> </body> </html> The le is ImageApplet0.html. The comments on ImageApplet0.java can be divided into those about how the image is displayed and some more general comments about the structure and behaviour of applets. First the image display. The drawing routines in Graphics can render an Image on the screen but rst it must be loaded from a le. Where is the le? An applet can be fetched from a server and run in a browser on any computer in the world (if connected), so there must be a way for it to nd its data le, its image. The getImage function has two arguments that are joined together to name the image le, the rst is a URL, it names the host machine and directory where the le is, and the last part is the le name. The URL could be built in and absolute to a named machine but this is inexible, the preferred solution is to nd out where the applet class came from and get the image from the same place. The function getCodeBase() returns a URL to the directory the applet came from. This works for remote systems needing networking and for local systems when the browser got an applet from the local computer. Next the structure of the applet. An applet is not an ordinary stand-alone program (there is no main), it is run inside a browser (or similar program), this means it can be stopped and started as other pages are visited, also it shares a browser window with other images and HTML stuff. What it does and what happens to it are known as the applet life-cycle: when the HTML le containing the <applet> tag is rst viewed the applet is loaded, at this point the class derived from the JApplet is used to create an applet object. At this time the: public void init() {...} function is called, it is used to do any initialisation, for example nding and fetching the image. Nothing needs to be drawn on the screen yet. the function: public void start() {...} is called whenever a page containing the applet is visited. The applet might be loaded in the browser but the user has been to other pages and has then gone back to the applet page. If the applet is doing some animation start can contain code to re-start the animation,
the other non-empty function is: public void paint(Graphics g) { this function is called by the surrounding system (usually a browser) whenever it thinks the applet needs to re-draw itself. This can be, for example, when the window is re-sized or when it is uncovered. The argument of type Graphics is associated with the screen that needs re-drawing and its is a way of accessing all the graphical functions, the function public void stop() is called when the applet can stop execution although it is not being killed. This happens when a browser visits a new page that replaces the one containing the applet, the function public void destroy() is called only when the applet is removed from the browser. The applet in ImageApplet0.java contains init which fetches the image once when the applet is loaded, and it denes paint to redraw the image whenever the browser thinks it necessary. The other functions start, stop and destroy are not needed by this applet (many applets dont need them) they have been included as empty do nothing functions, however this isnt really necessary as the parent class JApplet has empty default versions of these functions.
Things to note about this program: The program generates a JFrame object and assigns it to the variable window, it then manipulates it by, in this case, adding an image to it. All graphical user interface objects in Java applications must be added to some container that can be displayed. The function getContentPane() returns the graphical object container of the JFrame. Unless objects, images, text, or buttons are added to this container (directly of indirectly) they will not appear in the window. See the next program for a different way to add to the content pane. There are different ways to display an image in a graphical user interface, the previous applet examples used the Graphics drawing routines. This program uses a GUI component called a JLabel, a label can be labelled with text or a picture, in this case an image. The difference between drawing and using a GUI component is that all the drawing and re-drawing of components (including images) is handled automatically by the JFrame, it does not need to use the paint function. It adds the component to the content pane. The operation window.pack() causes the JFrame to calculate the size of all the components added to the content pane, without this the components wont appear on the window. Finally it is necessary to call window.setVisible(true), without this the whole window belonging to the JFrame wont be shown in the screen. The window can be hidden again by calling window.setVisible(false). In older versions of Java making the window visible was done by window.show() but this is now depreceated.
content.add(caption); content.add(pic); window.setContentPane(content); window.pack(); window.setVisible(true); } } The program is in the le TuxApp2.java and the image in tux-smaller.jpg. notice there are two components side by side: This is what is displayed,
public class TuxApp3 { public static void main(String args[]) { TuxFrame window = new TuxFrame(); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); window.setVisible(true); } } The program is in the le TuxApp3.java and the image in tux-smaller.jpg. the class has three data attributes to hold its components: the JPanel, for the new content pane, and two JLabels. in this program all the work is done in the constructor to build the window components, for this simple program no other functions are required, notice one important result of building inside the object, instead of from outside as before, the same operations are still needed: setting the content pane and packing but they are now called differently. In the previous program a JFrame object was created and assigned to the variable window, then the pane was set and packed with: window.setContentPane(content); window.pack(); now, in the constructor for TuxFrame the same job is accomplished with: setContentPane(content); pack(); Why the difference? This code is being executed inside a newly created object, the functions getContentPane and pack are also functions inside TuxFrame (inherited from JFrame) so we can call them directly. These functions are inside the same object as the constructor containing the calls not inside some separate object in a variable that requires the variable name and dot to nd them. the only task for main is to create a TuxFrame object: TuxFrame window = new TuxFrame(); this will cause execution of the constructor inside the object and the creation of our window with two labels. There is only one of the operations that has been left outside the object, ie. it is not in the constructor, and that is the setVisible(true) call. It could have been put inside, in which case the window. prex would be dropped. It has been left out because I thought that while it is appropriate for the new object type TuxFrame to build itself, the decision about whether and when to display it (make it visible) should be left to the code that decides when and if to create it. There is one other change in this program that is not related to the decision to switch to using inheritance rather than a JFrame object. It is a separate gratuitous decision. The line: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); means that if the window is closed the program stops. Without this Java will allow the window to be closed but the program is still running, not doing anything useful because its lost its display, but still not dead.
3.1.1 Program TextAreaApp0.java This version uses a JFrame object: import java.awt.*; import javax.swing.*; class TextAreaApp0 { public static void main(String args[]) { JFrame win = new JFrame(); Container myWindow = win.getContentPane(); JTextArea messages = new JTextArea(12,20); messages.append("This is a message\n"); messages.append("This is another message\n"); messages.append("Yet another message\n"); myWindow.add(messages); win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); win.pack(); win.setVisible(true); } } The program is in the le TextAreaApp0.java. Running TextAreaApp0.java:
Notes: This uses the simple JFrame structure, just an object, no inheritance, a JTextArea is a GUI component that can just hold text. You can append strings to it, when it can created it is given an initial numbers of rows and columns. this very simple program is only adding one component to the windows content pane so instead of creating a JPanel and setting that as the content pane, it uses the existing content pane. To do this it calls getContentPane() and just adds its single component textarea to that. 3.1.2 Program TextAreaApp1.java This version denes a new class using inheritance but the functionality should be similar to the previous program. import java.awt.*; import javax.swing.*; class TextFrame extends JFrame { Container myWindow; JTextArea messages; public TextFrame() {
myWindow = getContentPane(); messages = new JTextArea(12,20); messages.append("This is a message\n"); messages.append("This is another message\n"); messages.append("Yet another message\n"); myWindow.add(messages); pack(); } } class TextAreaApp1 { public static void main(String args[]) { TextFrame win = new TextFrame(); win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); win.setVisible(true); } } The program is in the le TextAreaApp1.java.
4 LAYOUT MANAGERS
Notes there is still a JTextArea to hold all the lines, it is still necessary to append strings to it, but now there is a JScrollPane and the JTextArea is put inside it (it is given as a parameter to the constructor of the JScrollPane when that is created), now the JScrollPane, not the JTextArea, is added to the frames content pane, without a scroller around a JTextArea it would grow as more lines were added to it, this could make a mess of the window. 3.2.2 Program ScrollApp1.java Using a new class: class ScrollFrame extends JFrame { Container myPane; JTextArea messages; JScrollPane scroller; public ScrollFrame() { myPane = getContentPane(); messages = new JTextArea(17,20); scroller = new JScrollPane(messages); myPane.add(scroller); for(int i=0; i<100; i++) { messages.append("message no: " + i + "\n"); } pack(); } } class ScrollApp1 { public static void main(String args[]) { ScrollFrame win = new ScrollFrame(); win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); win.setVisible(true); } } The program is in the le ScrollApp1.java.
4 Layout managers
A layout manager is a hidden, invisible component that can be added to a container to control the way that multiple components are positioned in the container. So depending on the layout manager when lots of components are added to a container they might be positioned differently. There are quite a few layout managers in Java:
4 LAYOUT MANAGERS
10
BorderLayout, allows the position of items relative to the edges of the container, BoxLayout, allows xed vertical or horizontal positioning, CardLayout, a layout that overlays components but allows the currently visible component to be changed, FlowLayout, the simplest, it just puts one component after another, the components are added left to right and warp round to another row depending on the dimensions of the container, GridLayout, has a xed number of rows and columns and adds components to the cells of the grid in order, the cells of the grid are all the same xed size, GridBagLayout, a much more complicated version of a GridLayout that allows cells to be different sizes, and others. This section will only consider the FlowLayout and BorderLayout managers.
public static void main(String args[]) { JFrame win = new JFrame(); Container myPane = win.getContentPane(); myPane.setLayout(new FlowLayout()); myPane.add(new JButton(" <One> ")); myPane.add(new JButton(" <Two> ")); myPane.add(new JButton("<Three>")); myPane.add(new JButton(" <Four>")); myPane.add(new JButton(" <Five> ")); myPane.add(new JButton(" <Six> ")); win.pack(); win.setVisible(true); } } The program is in the le LayoutApp0.java. Running LayoutApp0.java:
Notes: Layout managers are added to containers (JPanels or content panes) to allow many GUI components to be added. Adding a FlowLayout manager to the standard content pane returned by getContentPane() makes it function like a JPanel. FlowLayout adds one component after another, left to right then top to bottom, in this case because the size isnt given the window is long and thin.
4 LAYOUT MANAGERS
11
4.1.2 LayOutApp1.java This time the program specied a preferred size for the JFrame and consequently for the container inside so that when components are added the FlowLayout manager positions them differently. import java.awt.*; import javax.swing.*; public class LayoutApp1 {
public static void main(String args[]) { JFrame win = new JFrame(); Container myPane = win.getContentPane(); myPane.setLayout(new FlowLayout()); myPane.add(new JButton(" <One> ")); myPane.add(new JButton(" <Two> ")); myPane.add(new JButton("<Three>")); myPane.add(new JButton(" <Four>")); myPane.add(new JButton(" <Five> ")); myPane.add(new JButton(" <Six> ")); win.setPreferredSize(new Dimension(200,140)); win.pack(); win.setVisible(true); } } The program is in the le LayoutApp1.java. Running LayoutApp1.java:
4 LAYOUT MANAGERS
12
Container myPane = win.getContentPane(); myPane.setLayout(new BorderLayout(5,5)); // 5,5 are x and y space between myPane.add(new myPane.add(new myPane.add(new myPane.add(new myPane.add(new JButton(" <One> "),BorderLayout.NORTH); JButton(" <Two> "),BorderLayout.SOUTH); JButton("<Three>"),BorderLayout.EAST); JButton(" <Four>"),BorderLayout.WEST); JButton(" <Five>"),BorderLayout.CENTER);
Notes: the BorderLayout allows you to place GUI in specic positions, it has positions NORTH, SOUTH, EAST, WEST, and CENTER, when the BorderLayout is created and assigned to a pane you can select the size of the borders between the components, borderlayouts behave in special ways when resized, try dragging a corner, it is usually the CENTER component that varies in size. 4.2.2 LayoutApp3.java This program shows that it is not necessary to use all the positions in a BorderLayout before packing it and displaying it: import java.awt.*; import javax.swing.*; public class LayoutApp3 {
public static void main(String args[]) { JFrame win = new JFrame(); Container myPane = win.getContentPane(); myPane.setLayout(new BorderLayout(5,5)); JButton top = new JButton(" <One> "); JButton mid = new JButton(" <Two> "); JButton bot = new JButton("<Three>"); bot.setPreferredSize(new Dimension(150,50)); myPane.add(top, BorderLayout.NORTH); myPane.add(mid, BorderLayout.CENTER); myPane.add(bot, BorderLayout.SOUTH); win.pack(); win.setVisible(true); } }
4 LAYOUT MANAGERS
13
Notes: You dont need to use all the ve positions in a border layout, this program just uses three, also the size of all the components is affect if you set the preferred size of one of them, but notice that because they are stacked vertically, it has affected the width but not the height of the other components, 4.2.3 LayoutApp4 This program shows different types of component being added to a BorderLayout manager. It also shows the effect on the others of specifying the size of one. import java.awt.*; import javax.swing.*; public class LayoutApp4 { public static void main(String args[]) { JFrame win = new JFrame(); Container myPane = win.getContentPane(); myPane.setLayout(new BorderLayout(5,5)); JLabel title = new JLabel("An example"); JTextArea ta = new JTextArea(10,20); JScrollPane sp = new JScrollPane(ta); JButton but = new JButton("Quit"); for(int i=0;i<12;i++) ta.append("hahaha\n"); myPane.add(title, BorderLayout.NORTH); myPane.add(sp, BorderLayout.CENTER); myPane.add(but, BorderLayout.SOUTH); win.pack(); win.setVisible(true); } } The program is in the le LayoutApp4.java. Running LayoutApp4.java:
4 LAYOUT MANAGERS
14
Notes: not all the components in a container have to be of the same type, here there are a JLabel, a JScrollPane, and a JButton, the same rules of sizing and resizing apply but when mixed with larger objects some of the smaller are enlarged toobe careful.
15
There is also another advantage with putting JPanels into a BorderLayout (or a GridLayout) and that is that with a JPanel components keep their preferred size and oat inside the panel, but with the BorderLayout components are stretched to ll the required size of the border layout cell.
functions
functions
The picture on the left shows the ow of control (sequence of execution) of a non-event-driven program, on the right an event-driven program. Note: the non-event-driven program starts in main, then the program decides which functions to call and it retains control of what is happening all the way to the end, in contrast the event-driven profram usually creates the GUI objects by calling constructors and then the main program path of execution terminates and the program waits. From then on all execution of functions is caused by user keyboard or mice events,
16
in the rst diagram the small broken line indicates input or output, in a non-event-driven program this only occurs when the path of execution of the program chooses to execute I/O statements. If the user types anything nothing will happen (it will probably be buffered by the operating system) until the program decides to get the input, in contrast, in the event-driven program mouse or keyboard activity immediately trigger execution of functions in the program.
5.2 ButtonEventApp1.java
import java.awt.*; import java.awt.event.*; import javax.swing.*; class ButtonFrame extends JFrame implements ActionListener Container myPane; JButton but; JTextArea text; int bcount; public ButtonFrame() { bcount = 0; myPane = getContentPane(); myPane.setLayout(new FlowLayout()); text = new JTextArea(10,15); myPane.add(text); but = new JButton("Press Me"); myPane.add(but); but.addActionListener(this); setPreferredSize(new Dimension(200,240)); pack(); } public void actionPerformed(ActionEvent e) { bcount++; text.append(e.getActionCommand()+" button pressed "+bcount+"\n"); } } public class ButtonEventApp1 { public static void main(String args[]) { ButtonFrame win = new ButtonFrame(); win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); win.setVisible(true); } } The program is in the le ButtonEventApp1.java. Running ButtonEventApp1.java: {
17
Notes: The handler for button events must always be called actionPerformed and it takes a parameter of type ActionEvent giving details of the event. The programmer must provide this function. the next task is to inform the Java runtime system about the event handler and associate it with the button. This is not done directly, instead it is necessary to tell the button which object contains the event handler function: but.addActionListener(this); this line means: tell the button but that the ActionListener (thats the object containing the function) for it to use is this, which is the main frame object that the constructor is in, the current object, Java requires that any class containing an actionPerformed function must implement ActionListener: class ButtonFrame extends JFrame implements ActionListener { the button generates events when it is clicked, these events are detected by the Java virtual machine that looks for the correct event handler. The actionPerformed function takes an object that contains information about the event, if the event parameter is e then e.getActionCommand() returns the name (label) of the button, in this program when the handler is executed it increments a counter and and adds a message to a textarea in the window.
5.3 ButtonEventApp2.java
This program just illustrates how a program handles events from more than one source. This program has three buttons. Once again there must be a function called actionPerformed, each button must be told that the current object contains the function. But when any button causes actionPerformed to be executed how does the code determine which button it was? The function e.getSource(), applied to the ActionEvent parameter returns the object causing the event, this can be compared with the variables holding the button objects. class ButtonFrame extends JFrame implements ActionListener Container myPane; JButton but1, but2, but3; JTextArea text; public ButtonFrame() { myPane = getContentPane(); myPane.setLayout(new FlowLayout()); text = new JTextArea(10,22); but1 = new JButton("Press Me"); myPane.add(text); myPane.add(but1); {
18
but2 = new JButton("PANIC"); myPane.add(but2); but3 = new JButton("Quit"); myPane.add(but3); but1.addActionListener(this); but2.addActionListener(this); but3.addActionListener(this); setPreferredSize(new Dimension(280,230)); pack(); } public void actionPerformed(ActionEvent e) { if(e.getSource() == but1) text.append("button 1 pressed\n"); else if(e.getSource() == but2) text.append("button 2 pressed\n"); else if(e.getSource() == but3) System.exit(0); else text.append("dont know what was pressed\n"); } } public class ButtonEventApp2 { public static void main(String args[]) { ButtonFrame win = new ButtonFrame(); win.setVisible(true); } } The program is in the le ButtonEventApp2.java. Running ButtonEventApp2.java:
5.4 ButtonEventApp5.java
This program shows that it is possible to create a separate special object to handle events, it doesnt have to be the main frame object. import java.awt.*; import java.awt.event.*; import javax.swing.*; class ButtonFrame extends JFrame {
private class MyActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { bcount++; text.append(e.getActionCommand()+" button pressed "+bcount+"\n"); } } Container myPane; JButton but;
19
JTextArea text; int bcount; public ButtonFrame() { bcount = 0; myPane = getContentPane(); myPane.setLayout(new FlowLayout()); MyActionListener listen = new MyActionListener(); text = new JTextArea(10,15); myPane.add(text); but = new JButton("Press Me"); myPane.add(but); but.addActionListener(listen); setPreferredSize(new Dimension(190,240)); pack(); } } public class ButtonEventApp5 { public static void main(String args[]) { ButtonFrame win = new ButtonFrame(); win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); win.setVisible(true); } } The program is in the le ButtonEventApp5.java. Notes on ButtonEventApp5.java: this shows an alternative way to handle events, it creates a small, special purpose, private, local class MyActionListener to make an object to handle the event rather than use the main JFrame object, notice the special class only has the handler inside, notice that a single object is created: MyActionListener listen = new MyActionListener(); it would be possible to write three separate local classes and create an object from each and each could have a different handler for three different buttons, however it is easier to use e.getSource()
5.5 TextFieldEventApp0.java
This program illustrates the handling of an event caused by a different component, a JTextField. A JTextField is intended to used for text input from the user. import java.awt.*; import java.awt.event.*; import javax.swing.*; class MyFrame extends JFrame implements ActionListener Container myPane; JButton but; JLabel inLab, res; JTextField inp; public MyFrame() { myPane = getContentPane(); myPane.setLayout(new FlowLayout()); inLab = new JLabel("inches: "); myPane.add(inLab); inp = new JTextField(5); myPane.add(inp); res = new JLabel("cms = 0.0"); myPane.add(res); but = new JButton("Quit"); myPane.add(but); inp.addActionListener(this); but.addActionListener(this); setPreferredSize(new Dimension(130,130)); pack(); }
20
public void actionPerformed(ActionEvent e) { if(e.getSource() == inp) { int n = Integer.parseInt(e.getActionCommand()); res.setText( "cms = " + n * 2.54); } else if(e.getSource() == but) System.exit(0); } } public class TextFieldEventApp0 { public static void main(String args[]) { MyFrame win = new MyFrame(); win.setVisible(true); } } The program is in the le TextFieldEventApp0java. Running TextFieldEventApp0.java:
Notes: a JTextField can hold only one line of text that can be entered by a user, when enter is typed it causes an ActionEvent, the button also causes an ActionEvent so the handler must use e.getSource to nd the source of the event, if it nds its the text eld then it uses getActionCommand() on its parameter e to get the string entered, (it could instead have called inp.getText()), which is a function to return the text from a JTextField.
the task is to produce a program that will accept a le name in a JTextField, open the le, read the le and display its contents in a scrolled JTextArea.
21
the program from last weeks practical did nearly all the work, I have provided a listing of program ScrollFileViewer1.java that you can download and modify, it is just necessary to add JTextField input, use some of the code from TextFieldEventApp0.java as a model, the major difference will be that you must open and read the le in the actionPerformed event handler, the rst version doesnt need a quit button, that is the second task, the third task is to try and catch the FileNotFoundException so that if the user mistypes the le name the program will not crash. Download and look at FileCopyExcept.java (also in the notes) for an example of how to catch this exception. 5.6.1 ScrollFileViewer1.java This is a simple solution to the previous exercise (not included here) to display a le in a scrolling text area. It is important because the exercise above can build on this program. import java.io.*; import java.awt.*; import javax.swing.*; class ScrollFrame extends JFrame { Container myPane; JTextArea messages; JScrollPane scroller; public ScrollFrame(String fname) throws Exception { String line; myPane = getContentPane(); messages = new JTextArea(17,20); scroller = new JScrollPane(messages); myPane.add(scroller); BufferedReader inpf=new BufferedReader(new FileReader(fname) ); line = inpf.readLine(); while(line != null) { messages.append(line + "\n"); line = inpf.readLine(); } pack(); } } class ScrollFileViewer1 { public static void main(String args[]) throws Exception { if(args.length != 1) { System.err.println("Need a filename"); System.exit(1); } ScrollFrame win = new ScrollFrame(args[0]); win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); win.setVisible(true); } } The program is in the le ScrollFileViewer1.java.
5.7 ListApp0.java
This program demonstrates use of a JScrollPane containing a JList which in turn contains an array of strings. The idea of using all these components together is that they allow single or multiple selections to be made from a list and for a ValueChanged event to be called, and the selection to be used.
22
class MyFrame extends JFrame implements ListSelectionListener { Container myPane; JTextArea messages; JList langList; JPanel bp; JScrollPane scroller; String listModel[]={ "Ada","Algol60","Algol68","APL","bash","Basic","BCPL","C", "C++","Cobol","CLU","CSP","Dylan","Eiffel","Forth", "Fortran","Haskell","Hope","Icon","Java","Javascript", "Lisp","Logo","Lua","Miranda","Modula","Modula2","Modula3", "Oberon","Occam","Pascal","Perl","PHP","PL/1","Pop-2", "Postscript","Prolog","Sather","SASL","Scheme","Simula-67"} public MyFrame() { myPane = getContentPane(); myPane.setLayout(new BorderLayout(5,5)); langList = new JList(listModel); langList.addListSelectionListener(this); scroller = new JScrollPane(langList); scroller.setPreferredSize(new Dimension(100,300)); myPane.add(scroller,BorderLayout.CENTER); bp = new JPanel(); messages = new JTextArea(5,18); bp.add(messages); myPane.add(bp,BorderLayout.SOUTH); setPreferredSize(new Dimension(240,420)); pack(); } public void valueChanged(ListSelectionEvent e) { if (! e.getValueIsAdjusting()) { messages.setText("you selected:"); int sels[]=langList.getSelectedIndices(); for(int i=0;i<sels.length;i++) { if(i % 4 == 0) messages.append("\n"); messages.append(listModel[sels[i]]+", "); } } } } public class ListApp0 { public static void main(String args[]) { MyFrame win = new MyFrame(); win.setVisible(true); } } The program is in the le ListApp0.java. Running ListApp0.java:
23
Notes: this program uses a JList. A list can contain an array of strings (called its data model) and allows one or more of the entries in the list to be selected, there is another type of event, a ListSelectionEvent, when a selection is made the event is triggered and the handler valueChanged (in a class object that implements ListSelectionListener) is called, the function in JList called getSelectedIndices() returns an array of the indices in the list that are selected, sometimes random events are called during selection, these can be avoid by checking if (! e.getValueIsAdjusting()). WARNING: JLists and their models are much more complicated than this note suggests, changing or modifying a list requires, at least, a DefaultListModel, so read more if you are going to use one.
24
class MouseFrame extends JFrame implements MouseListener, MouseMotionListener { static final String message = "Move, drag or click mouse"; JLabel report, messageLabel; Container myWin; public MouseFrame() { myWin = getContentPane(); myWin.setLayout(new BorderLayout()); messageLabel = new JLabel(message); myWin.add(messageLabel, BorderLayout.NORTH); report = new JLabel(); myWin.add(report, BorderLayout.SOUTH); addMouseMotionListener(this); addMouseListener(this); setPreferredSize(new Dimension(250,180)); pack(); } public void mousePressed(MouseEvent e) { reportEvent("Mouse down " + e.getX()+ " " + e.getY()); } public void mouseReleased(MouseEvent e) { reportEvent("Mouse up " + e.getX()+ " " + e.getY()); } public void mouseClicked(MouseEvent e) { reportEvent("Mouse clicked " + e.getX()+ " " + e.getY()); } public void mouseEntered(MouseEvent e) { reportEvent("Mouse entered"); } public void mouseExited(MouseEvent e) { reportEvent("Mouse exited"); } public void mouseDragged(MouseEvent e) { reportEvent("Mouse dragged at: " + e.getX()+ " " + e.getY()); } public void mouseMoved(MouseEvent e) { reportEvent("Mouse moved at: " + e.getX()+ " " + e.getY()); } private void reportEvent(String m) { report.setText(m); } } public class MouseEventsApp3 { public static void main(String args[]) { MouseFrame win = new MouseFrame(); win.setVisible(true); } } The program is in the le MouseEventsApp3.java.