1 / 107

Continuation From L ast T ime

Continuation From L ast T ime. A Third Swing App: ColorPanelApp. JFrame. Specification: An app with three sliders that the user can drag to change the RGB values of the background color Useful classes: JFrame , JPanel , JSlider , ChangeListener. JSlider. JPanel. DEMO: ColorPanelApp.

nakia
Download Presentation

Continuation From L ast T ime

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Continuation From Last Time

  2. A Third Swing App: ColorPanelApp JFrame • Specification: An app with three sliders that the user can drag to change the RGB values of the background color • Useful classes: JFrame, JPanel, JSlider, ChangeListener JSlider JPanel

  3. DEMO: ColorPanelApp

  4. Using JSliders • A JSliderlets the user graphically select a value by sliding an arrow within a bounded interval • One way to construct is by passing two ints (minimum and maximum values) as arguments: JSlider slider = new JSlider(0, 30); • To get the value of the slider, we can use the getValue method • A JSlideremits ChangeEvents when value changes-- to listen for them, we use a ChangeListener

  5. ChangeListeners ChangeListener ChangeEvent e JSlider ChangeEvent e public void stateChanged( ) { // Respond to ChangeEvent here! // (print something to the console, tell // a JLabel to update its text, etc.) }

  6. Process: ColorPanelApp JFrame • Create top-level class that contains a JFrame • Write a subclass of JPanelthat contains three JSliders, add an instance of it to the JFrame • Write a ChangeListenerthat changes a JPanel’s color based on value of a JSlider • Add ChangeListeners to the JSliders JSlider JPanel

  7. Top-level Class: ColorPanelApp • This top-level class is almost identical to those of the other examples-- we follow same pattern of setting up JFrame • Instantiate JFrame, set its close operation, call packand setVisible public class ColorPanelApp { public ColorPanelApp() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { new ColorPanelApp(); } }

  8. Process: ColorPanelApp JFrame • Create top-level class that contains a JFrame • Write a subclass of JPanel that contains three JSliders, add an instance of it to the JFrame • Write a ChangeListenerthat changes a JPanel’s color based on value of a JSlider • Add ChangeListeners to the JSliders JSlider JPanel

  9. JPanelSubclass: ColorPanel • ColorPanel“is a” JPanel • As in other examples, create a Dimension, give it desired width and height, then call setPreferredSize • Want panel to start out gray, so call method setBackground public class ColorPanel extends JPanel { public ColorPanel() { Dimension panelSize = new Dimension(300, 150); this.setPreferredSize(panelSize); this.setBackground(Color.GRAY); JSlider sliderRed = new JSlider(0, 255); JSlider sliderGreen = new JSlider(0, 255); JSlider sliderBlue = new JSlider(0, 255); this.add(sliderRed); this.add(sliderGreen); this.add(sliderBlue); } }

  10. JPanelSubclass: ColorPanel public class ColorPanel extends JPanel { public ColorPanel() { Dimension panelSize = new Dimension(300, 150); this.setPreferredSize(panelSize); this.setBackground(Color.GRAY); JSlidersliderRed = new JSlider(0, 255); JSlidersliderGreen = new JSlider(0, 255); JSlidersliderBlue = new JSlider(0, 255); this.add(sliderRed); this.add(sliderGreen); this.add(sliderBlue); } } • Instantiate three JSliders: one to control each channel (red, green, and blue) • Arguments are beginning/end of slider’s range: we give each range 0-255 (one byte/RGB channel) • Finally, add each slider to panel

  11. Adding a ColorPanelAppto theJFrame public class ColorPanelApp { public ColorPanelApp() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); ColorPanel panel = new ColorPanel(); frame.add(panel); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { new ColorPanelApp(); } } • Just as we did in previous examples, first instantiate a panel, then call addto add it to the JFrame

  12. Process: ColorPanelApp JFrame • Create top-level class that contains a JFrame • Write a subclass of JPanel that contains three JSliders, add an instance of it to the JFrame • Write a ChangeListener that changes a JPanel’s color based on value of a JSlider • Add ChangeListeners to the JSliders JSlider JPanel

  13. Changing a JPanel’s Color • Every JPanelhas a pair of accessor and mutator methods, setBackgroundand getBackground • We have three JSliders-- one to control each color channel of the Jpanel.EachJslider has its own listener • When red slider’s listener detects that its slider has been moved: • it calls getBackgroundto ask the panel for its current color • it creates a new instance of Color, using the “R” value from the slider and the “G” and “B” values from the panel’s current background color (since they haven’t changed) • it calls setBackground, passing in the new Color

  14. Our ChangeListener: SliderListener • A SliderListener’s job is to change the color of a JPanelbased on the value of a JSlider • Since JSliders emit ChangeEvents whenever their value changes, SliderListenerimplements ChangeListener interface • Defines method stateChanged. SliderListener will be coded generically so it can be used for each slider public class SliderListener implements ChangeListener { private JPanel _panel; private int _channel; private JSlider _slider; public SliderListener(JPanel panel, int channel, JSlider slider){ _panel = panel; _channel = channel; _slider = slider; } @Override public void stateChanged(ChangeEvent e) { // implementation elided for now } }

  15. Our ChangeListener: SliderListener • To do its job, it needs to know three things: • The JPanelwhose color it should change • Which channel (red, green, or blue) to modify • Which slider it listens to • We’ll represent the channel as an int: 0 means red, 1 means green, 2 means blue public class SliderListener implements ChangeListener { private JPanel _panel; private int _channel; private JSlider _slider; public SliderListener(JPanel panel, int channel, JSlider slider){ _panel = panel; _channel = channel; _slider = slider; } @Override public void stateChanged(ChangeEvent e) { // implementation elided for now } }

  16. The stateChangedmethod // rest of class SliderListenerelided for now @Override public void stateChanged(ChangeEvent e) { int val = _slider.getValue(); Color bg = _panel.getBackground(); Color newbg; switch(_channel){ case 0: newbg = new Color(val, bg.getGreen(), bg.getBlue()); break; case 1: newbg = new Color(bg.getRed(), val, bg.getBlue()); break; default: newbg = new Color(bg.getRed(), bg.getGreen(), val); } _panel.setBackground(newbg); } } • Method is called whenever value of the listener’s JSliderchanges • Should modify the appropriate color channel of the JPanel’s background color • Must take in a ChangeEvent as a parameter, because it is required by the ChangeListener interface; doesn’t use it in this case

  17. The stateChangedmethod // rest of class SliderListenerelided for now @Override public void stateChanged(ChangeEvent e) { int val = _slider.getValue(); Color bg = _panel.getBackground(); Color newbg; switch(_channel){ case 0: newbg = new Color(val, bg.getGreen(), bg.getBlue()); break; case 1: newbg = new Color(bg.getRed(), val, bg.getBlue()); break; default: newbg = new Color(bg.getRed(), bg.getGreen(), val); } _panel.setBackground(newbg); } } • Need to determine new value of JSlider • Since we know the source is the JSlider, we can retrieve value by calling getValueon _slider

  18. The stateChangedmethod // rest of class SliderListenerelided for now @Override public void stateChanged(ChangeEvent e) { int val = _slider.getValue(); Color bg = _panel.getBackground(); Color newbg; switch(_channel){ case 0: newbg = new Color(val, bg.getGreen(), bg.getBlue()); break; case 1: newbg = new Color(bg.getRed(), val, bg.getBlue()); break; default: newbg = new Color(bg.getRed(), bg.getGreen(), val); } _panel.setBackground(newbg); } } • Next, we get the JPanel’s current background color • We declare a new Color, newBg, to which we’ll assign a different value based on which color channel the listener is supposed to change

  19. The stateChangedmethod // rest of class SliderListenerelided for now @Override public void stateChanged(ChangeEvent e) { int val = _slider.getValue(); Color bg = _panel.getBackground(); Color newbg; switch(_channel){ case 0: newbg = new Color(val, bg.getGreen(), bg.getBlue()); break; case 1: newbg = new Color(bg.getRed(), val, bg.getBlue()); break; default: newbg = new Color(bg.getRed(), bg.getGreen(), val); } _panel.setBackground(newbg); } } • Depending on the value of _channel, we set newBgto a different color • In each case, only the specified color channel changes; we use the gets for the values of the unchanged channels • Once we’ve changed the appropriate channel, we set the JPanel’s background color to newBg

  20. Process: ColorPanelApp JFrame • Create top-level class that contains a JFrame • Write a subclass of JPanel that contains three JSliders, add an instance of it to the JFrame • Write a ChangeListener that changes a JPanel’s color based on value of a JSlider • Add ChangeListeners to the JSliders JSlider JPanel

  21. Setting up our SliderListeners public class ColorPanel extends JPanel { public ColorPanel() { Dimension panelSize = new Dimension(300, 150); this.setPreferredSize(panelSize); this.setBackground(Color.GRAY); JSlidersliderRed = new JSlider(0, 255); JSlidersliderGreen = new JSlider(0, 255); JSlidersliderBlue = new JSlider(0, 255); sliderRed.addChangeListener( new SliderListener(this, 0, sliderRed)); sliderGreen.addChangeListener( new SliderListener(this, 1, sliderGreen)); sliderBlue.addChangeListener( new SliderListener(this, 2, sliderBlue)); this.add(sliderRed); this.add(sliderGreen); this.add(sliderBlue); } } • Back in ColorPanel class • Call method addChangeListeneron each slider, passing in a new instance of SliderListener • Pass in ColorPanel, appropriate channel number and slider as arguments to each SliderListener

  22. The Whole App (1/2) public class ColorPanel extends JPanel { public ColorPanel() { Dimension panelSize = new Dimension(300, 150); this.setPreferredSize(panelSize); this.setBackground(Color.GRAY); JSlidersliderRed = new JSlider(0, 255); JSlidersliderGreen = new JSlider(0, 255); JSlidersliderBlue = new JSlider(0, 255); sliderRed.addChangeListener( new SliderListener(this, 0, sliderRed)); sliderGreen.addChangeListener( new SliderListener(this, 1, sliderGreen)); sliderBlue.addChangeListener( new SliderListener(this, 2, sliderBlue)); this.add(sliderRed); this.add(sliderGreen); this.add(sliderBlue); } } public class ColorPanelApp { public ColorPanelApp() { JFrame frame = new JFrame(); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); ColorPanel panel = new ColorPanel(); frame.add(panel); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { new ColorPanelApp(); } }

  23. The Whole App (2/2) @Override public void stateChanged(ChangeEvent e) { int val = _slider.getValue(); Color bg = _panel.getBackground(); Color newbg; • switch(_channel){ • case 0: • newbg = new Color(val, bg.getGreen(), • bg.getBlue()); • break; • case 1: • newbg = new Color(bg.getRed(), val, • bg.getBlue()); • break; • default: • newbg = new Color(bg.getRed(), bg.getGreen(), • val); • } • _panel.setBackground(newbg);} } public class SliderListener implements ChangeListener { private JPanel _panel; private int _channel; public SliderListener(JPanel panel, int channel){ _panel = panel; _channel = channel; }

  24. Putting It All Together: ColorPanelApp ColorPanelApp JFrame ColorPanel JSlider SliderListener

  25. Buttons in Swing Some buttons in Swing: • javax.swing.JButton • javax.swing.JToggleButton • javax.swing.JCheckBox • javax.swing.JRadioButton

  26. Buttons in Swing

  27. ButtonGroups • How do we make options mutually exclusive (i.e. you can only click one button at a time)? • put them in a button group • javax.swing.ButtonGroup • Buttons that can be added to ButtonGroup: JRadioButton JToggleButton JMenuItem (for advanced users)

  28. JRadioButtons & ButtonGroups • How to use a ButtonGroup: • create buttons JRadioButton rB1 = new JRadioButton(“Green, not Red”); JRadioButton rB2 = new JRadioButton(“Red, not Green”); • create ButtonGroup ButtonGroup bGroup = new ButtonGroup(); • add buttons to ButtonGroup bGroup.add(rB1); bGroup.add(rB2);

  29. Modified ColorTextApp: RadioColorListener public class RadioColorListener implements ActionListener { private JLabel _label; private Color _currentColor public RadioColorListener(JLabel label, Color color) { _label = label; _currentColor = color; } @Override public void actionPerformed(ActionEvent e) { _label.setForeground(_currentColor); } }

  30. Modified ColorTextApp: ColorTextPanel Assume all the swing components are imported! public class ColorTextPanel extends JPanel { public ColorTextPanel() { JLabel label = new JLabel("CS15 Rocks!"); JRadioButton buttonForRed = new JRadioButton("Red"); JRadioButton buttonForGreen = new JRadioButton(“Green); RadioColorListener redListener = new RadioColorListener(label, Color.RED); RadioColorListener greenListener = new RadioColorListener(label, Color.GREEN); //add listeners to their buttons buttonForRed.addActionListener(redListener); buttonForGreen.addActionListener(greenListener); //create button group and add buttons to it ButtonGroup buttonGroup = new ButtonGroup(); buttonGroup.add(buttonForRed); buttonGroup.add(buttonForGreen); Dimension panelSize = new Dimension(300,100); this.setPreferredSize(panelSize); //add label and buttons to ColorTextPanel this.add(label); this.add(buttonForRed); this.add(buttonForGreen); } } For more complex projects you might want to give the Buttons a separate JPanel and use LayoutManagers (stay tuned!)

  31. More Complicated Swing Apps • The examples we’ve seen so far have been small and simple • What if we want to construct a more realistic GUI? • We can use LayoutManagers to arrange components nicely within JPanels

  32. Using java.awt.LayoutManagers • Each JPanelcontains a LayoutManagerto automatically arrange its sub-components • LayoutManagerinterface implemented by classes: • java.awt.FlowLayout • java.awt.GridLayout • java.awt.BorderLayout • To specify the LayoutManagerfor a JPanel, either pass an instance of one of these classes to the panel’s constructor or to its setLayoutmethod later

  33. FlowLayout • Default layout used by all JPanels • Arranges components from left to right, top to bottom • When it reaches the edge of the panel, moves to next row

  34. FlowLayout public class FlowTest extends JFrame { public FlowTest() { super(); this.setSize(200, 300); JButton b1 = new JButton(“One”); JButton b2 = new JButton(“Two”); JButton b3 = new JButton(“Tree”); JButton b4 = new JButton(“Four”); JButton b5 = new JButton(“Five”); JButton b6 = new JButton(“Six”); JPanelmainPanel = new JPanel(); FlowLayoutfl= new Flowlayout(); mainPanel.setLayout(fl); mainPanel.add(b1); mainPanel.add(b2); mainPanel.add(b3); mainPanel.add(b4); mainPanel.add(b5); mainPanel.add(b6); this.add(mainPanel); this.pack(); this.setVisible(true); } }

  35. GridLayout • Arranges components in a grid • Add components left to right, top to bottom • Must specify grid size in constructor-- number of rows and columns • Each cell in grid is same size, determined by largest element in grid

  36. GridLayout public class GridTest extends JFrame { public GridTest() { super(); this.setSize(200, 300); JPanel p1 = new JPanel(); JPanel p2 = new JPanel(); JPanel p3 = new JPanel(); JPanel p4 = new JPanel(); JPanel p5 = new JPanel(); JPanel p6 = new JPanel(); JPanel mainPanel = new JPanel(); p1.setBackground(Color.GREEN); p2.setBackground(Color.RED); p3.setBackground(Color.ORANGE); p4.setBackground(Color.CYAN); p5.setBackground(Color.BLUE); p6.setBackground(Color.YELLOW); GridLayout gl = new GridLayout(3, 2); mainPanel.setLayout(gl); mainPanel.add(p1); mainPanel.add(p2); mainPanel.add(p3); mainPanel.add(p4); mainPanel.add(p5); mainPanel.add(p6); this.add(mainPanel); this.pack(); this.setVisible(true); } }

  37. BorderLayout • Splits JPanelinto 5 regions: NORTH, SOUTH, EAST, WEST, CENTER • These are all static constants • Must specify region when adding component to its container

  38. BorderLayout • Don’t have to fill all regions-- default size of a region is (0, 0) • BorderLayoutwill adjust dynamically depending on what has been added • Typically add to CENTERfirst-- it should be largest

  39. BorderLayout public class BorderTest extends JFrame { public BorderTest() { super(); this.setSize(300, 200); JPanel p1 = new JPanel(); JPanel p2 = new JPanel(); JPanel p3 = new JPanel(); JPanel p4 = new JPanel(); JPanel p5 = new JPanel(); JPanel mainPanel = new JPanel(); p1.setBackground(Color.RED); p2.setBackground(Color.GREEN); p3.setBackground(Color.ORANGE); p4.setBackground(Color.CYAN); p5.setBackground(Color.BLUE); BorderLayout bl = new BorderLayout(); mainPanel.setLayout(bl); mainPanel.add(p1, BorderLayout.CENTER); mainPanel.add(p2, BorderLayout.NORTH); mainPanel.add(p3, BorderLayout.SOUTH); mainPanel.add(p4, BorderLayout.EAST); mainPanel.add(p5, BorderLayout.WEST); this.add(mainPanel); this.pack(); this.setVisible(true); } }

  40. LayoutManagers • You’ll be using layouts a lot in CS15-- practice playing around with them! • Try taking the previous example and calling setPreferredSizeon each sub-panel to change their sizes and shapes • If you want to test your understanding (and want to get a headstart on Cartoon), try making something like this:

  41. LayoutManagers

  42. Swing: Summary • Swing has a variety of tools to help you make GUIs: • JFrames, JPanels, JButtons, and JSliders, arranged using LayoutManagers • ActionListeners and ChangeListeners to respond to user input • Timers to perform a task at regular intervals • On future projects, instead of relying on support code for graphical elements, you will use these tools yourself!

  43. Lecture 10 Build Your Own Custom Graphics

  44. Creating Custom Graphics • Last lecture, we introduced you to Swing • Lots of handy widgets for making your own graphical applications! • What if you want to create and display your own custom graphics? • This lecture: build your own graphics using TA-written Shapepackage and work them into Swing applications

  45. java.awt.geom.RectangularShapes • Swing provides built-in classes to represent a small amount of geometric information for 2D shapes – they can’t even draw themselves! • Subclasses of RectangularShape (Rectangle2D, Ellipse2D, etc.) know how to do a few basic things: • e.g., set and get their current size and graphical position

  46. The Problem • We need way more functionality than built-in RectangularShapes provide! • Want all shapes to be able to: • Set and get current color • Have a border of user-specified width and color • Rotate • Know how to paint themselves on the screen!

  47. The Solution: Shape • The TAs have written the Shape package to provide you with “smart shapes” that have all these capabilities and more! • You’ll be using Shape subclassesto create beautiful graphics for the rest of the semester

  48. Shape Package • To use the TAs’ Shapepackage, import it using • import cs015.prj.Shape.*; • Make your own subclass by extending the Shapeclass in the Shape package and passing a java.awt.geom.RectuangularShapeinto super’s constructor.

  49. Shape Class Hierarchy Shape • Shape package also contains specific shapes: e.g., RectangleShape (don’t confuse with RectangularShape) and EllipseShape • Subclasses of abstract Shape class • All Shapeskeep track of a basic set of properties for which they have accessors and mutators RectangleShape EllipseShape

  50. Accessors and mutators of Shapes Location public double getX(); public double getY(); public void setLocation(double x, double y); Border Size public int getBorderWidth(); public void setBorderWidth(int width); public double getWidth(); public double getHeight(); public void setSize(double width, double height); Visibility Color public boolean getVisible(); public void setVisible(boolean visible); public Color getBorderColor(); public Color getFillColor(); public void setBorderColor(Color c); public void setFillColor(Color c); // set both border and fill to same color public void setColor(Color c); Rotation public double getRotation(); public void setRotation(double degrees);

More Related