Complete listings of the source code discussed in this lesson are shown in Listing 10 and Listing 11 below.
Listing 10. Prob12.java |
---|
/*File Prob12 Copyright 2012 R.G.Baldwin The purpose of this program is to demonstrate how to get a color value from a PictureExplorer object and to display it in JTextField object. It also demonstrates how to access and use a reference to a JFrame object that serves as the container for a PictureExplorer object. Finally, it demonstrates how to disable the X-button in a PictureExplorer object. Note that this program requires access to a modified version of the PictureExplorier class. *********************************************************/ import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.JLabel; import javax.swing.WindowConstants; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.GridLayout; import java.awt.Color; public class Prob12{ public static void main(String[] args){ new Prob12Runner(); }//end main method }//end class Prob12 //======================================================// class Prob12Runner extends JFrame{ private JFrame explorerFrame = null; private PictureExplorer explorer = null; private Picture pix; private JPanel controlPanel = new JPanel(); private JPanel colorPanel = new JPanel(); private JPanel buttonPanel = new JPanel(); private JTextField redField = new JTextField("000000"); private JButton getDataButton = new JButton( "Get and Display Red Color Value"); private String fileName = "Prob12.jpg"; //----------------------------------------------------// public Prob12Runner(){//constructor controlPanel.setLayout(new GridLayout(2,1)); controlPanel.add(colorPanel); controlPanel.add(buttonPanel); colorPanel.setBackground(Color.RED); colorPanel.add(new JLabel( "Red pixel Color at Cursor: ")); colorPanel.add(redField); buttonPanel.setBackground(Color.BLUE); buttonPanel.add(getDataButton); getContentPane().add(controlPanel); setTitle("Dick Baldwin"); setVisible(true); //Create a Picture object and add a name to // the picture before using it to construct the // PictureExplorer object. pix = new Picture(fileName); pix.addMessage("Dick Baldwin",10,20); //Create a PictureExplorer object containing the // picture and set its default close operation. explorer = new PictureExplorer(pix); //Get a ref to the JFrame in the PictureExplorer // object. explorerFrame = explorer.getFrame(); explorerFrame.setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE); //Set the size of the control GUI. setSize(explorerFrame.getWidth(),110); //Set the location for the control GUI immediately // below the PictureExplorer object, and set its // default close operation. setLocation(0,explorerFrame.getHeight()); setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE); //--------------------------------------------------// //Register a listener object on the button. //--------------------------------------------------// getDataButton.addActionListener( new ActionListener(){ public void actionPerformed(ActionEvent e){ redField.setText(explorer.getRValue()); }//end action performed }//end newActionListener );//end addActionListener //--------------------------------------------------// }//end constructor }//end class Prob12Runner |
Listing 11. Modified PictureExplorer.java |
---|
import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.awt.image.*; import javax.swing.border.*; /* 05/15/12 Modified by Baldwin to add getter methods to cause the following values to be accessible from outside the PictureExplorer object: Red color value Reference to the JFrame containing the PictureExplorer object. Also disabled the call to setDefaultCloseOperation */ /** * Displays a picture and lets you explore the picture by displaying the x, y, red, * green, and blue values of the pixel at the cursor when you click a mouse button or * press and hold a mouse button while moving the cursor. It also lets you zoom in or * out. You can also type in a x and y value to see the color at that location. * * Originally created for the Jython Environment for Students (JES). * Modified to work with DrJava by Barbara Ericson * * Copyright Georgia Institute of Technology 2004 * @author Keith McDermottt, gte047w@cc.gatech.edu * @author Barb Ericson ericson@cc.gatech.edu */ public class PictureExplorer implements MouseMotionListener, ActionListener, MouseListener { // current x and y index private int xIndex = 0; private int yIndex = 0; //Main gui variables private JFrame pictureFrame; private JScrollPane scrollPane; //information bar variables private JLabel xLabel; private JButton xPrevButton; private JButton yPrevButton; private JButton xNextButton; private JButton yNextButton; private JLabel yLabel; private JTextField xValue; private JTextField yValue; private JLabel rValue; private JLabel gValue; private JLabel bValue; private JLabel colorLabel; private JPanel colorPanel; // menu components private JMenuBar menuBar; private JMenu zoomMenu; private JMenuItem twentyFive; private JMenuItem fifty; private JMenuItem seventyFive; private JMenuItem hundred; private JMenuItem hundredFifty; private JMenuItem twoHundred; private JMenuItem fiveHundred; /** The picture being explored */ private DigitalPicture picture; /** The image icon used to display the picture */ private ImageIcon scrollImageIcon; /** The image display */ private ImageDisplay imageDisplay; /** the zoom factor (amount to zoom) */ private double zoomFactor; /** the number system to use, 0 means starting at 0, 1 means starting at 1 */ private int numberBase=0; /** * Public constructor * @param picture the picture to explore */ public PictureExplorer(DigitalPicture picture) { // set the fields this.picture=picture; zoomFactor=1; // create the window and set things up createWindow(); } //===Methods added by Baldwin on 05/15/12===============// //Method to get the red color value as text. public String getRValue(){ return rValue.getText(); }//end getRValue //Method to get a reference to the JFrame containing // the PictureExplorer object. public JFrame getFrame(){ return pictureFrame; }//end getFrame() //===End methods added by Baldwin on 05/15/12===========// /** * Changes the number system to start at one */ public void changeToBaseOne() { numberBase=1; } /** * Set the title of the frame *@param title the title to use in the JFrame */ public void setTitle(String title) { pictureFrame.setTitle(title); } /** * Method to create and initialize the picture frame */ private void createAndInitPictureFrame() { pictureFrame = new JFrame(); // create the JFrame pictureFrame.setResizable(true); // allow the user to resize it pictureFrame.getContentPane().setLayout(new BorderLayout()); // use border layout /*Disabled by Baldwin on 5/15/12 pictureFrame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE); */ pictureFrame.setTitle(picture.getTitle()); PictureExplorerFocusTraversalPolicy newPolicy = new PictureExplorerFocusTraversalPolicy(); pictureFrame.setFocusTraversalPolicy(newPolicy); } /** * Method to create the menu bar, menus, and menu items */ private void setUpMenuBar() { //create menu menuBar = new JMenuBar(); zoomMenu = new JMenu("Zoom"); twentyFive = new JMenuItem("25%"); fifty = new JMenuItem("50%"); seventyFive = new JMenuItem("75%"); hundred = new JMenuItem("100%"); hundred.setEnabled(false); hundredFifty = new JMenuItem("150%"); twoHundred = new JMenuItem("200%"); fiveHundred = new JMenuItem("500%"); // add the action listeners twentyFive.addActionListener(this); fifty.addActionListener(this); seventyFive.addActionListener(this); hundred.addActionListener(this); hundredFifty.addActionListener(this); twoHundred.addActionListener(this); fiveHundred.addActionListener(this); // add the menu items to the menus zoomMenu.add(twentyFive); zoomMenu.add(fifty); zoomMenu.add(seventyFive); zoomMenu.add(hundred); zoomMenu.add(hundredFifty); zoomMenu.add(twoHundred); zoomMenu.add(fiveHundred); menuBar.add(zoomMenu); // set the menu bar to this menu pictureFrame.setJMenuBar(menuBar); } /** * Create and initialize the scrolling image */ private void createAndInitScrollingImage() { scrollPane = new JScrollPane(); BufferedImage bimg = picture.getBufferedImage(); imageDisplay = new ImageDisplay(bimg); imageDisplay.addMouseMotionListener(this); imageDisplay.addMouseListener(this); imageDisplay.setToolTipText("Click a mouse button on a pixel to see the pixel information"); scrollPane.setViewportView(imageDisplay); pictureFrame.getContentPane().add(scrollPane, BorderLayout.CENTER); } /** * Creates the JFrame and sets everything up */ private void createWindow() { // create the picture frame and initialize it createAndInitPictureFrame(); // set up the menu bar setUpMenuBar(); //create the information panel createInfoPanel(); //creates the scrollpane for the picture createAndInitScrollingImage(); // show the picture in the frame at the size it needs to be pictureFrame.pack(); pictureFrame.setVisible(true); } /** * Method to set up the next and previous buttons for the * pixel location information */ private void setUpNextAndPreviousButtons() { // create the image icons for the buttons Icon prevIcon = new ImageIcon(SoundExplorer.class.getResource("leftArrow.gif"), "previous index"); Icon nextIcon = new ImageIcon(SoundExplorer.class.getResource("rightArrow.gif"), "next index"); // create the arrow buttons xPrevButton = new JButton(prevIcon); xNextButton = new JButton(nextIcon); yPrevButton = new JButton(prevIcon); yNextButton = new JButton(nextIcon); // set the tool tip text xNextButton.setToolTipText("Click to go to the next x value"); xPrevButton.setToolTipText("Click to go to the previous x value"); yNextButton.setToolTipText("Click to go to the next y value"); yPrevButton.setToolTipText("Click to go to the previous y value"); // set the sizes of the buttons int prevWidth = prevIcon.getIconWidth() + 2; int nextWidth = nextIcon.getIconWidth() + 2; int prevHeight = prevIcon.getIconHeight() + 2; int nextHeight = nextIcon.getIconHeight() + 2; Dimension prevDimension = new Dimension(prevWidth,prevHeight); Dimension nextDimension = new Dimension(nextWidth, nextHeight); xPrevButton.setPreferredSize(prevDimension); yPrevButton.setPreferredSize(prevDimension); xNextButton.setPreferredSize(nextDimension); yNextButton.setPreferredSize(nextDimension); // handle previous x button press xPrevButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { xIndex--; if (xIndex < 0) xIndex = 0; displayPixelInformation(xIndex,yIndex); } }); // handle previous y button press yPrevButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { yIndex--; if (yIndex < 0) yIndex = 0; displayPixelInformation(xIndex,yIndex); } }); // handle next x button press xNextButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { xIndex++; if (xIndex >= picture.getWidth()) xIndex = picture.getWidth() - 1; displayPixelInformation(xIndex,yIndex); } }); // handle next y button press yNextButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { yIndex++; if (yIndex >= picture.getHeight()) yIndex = picture.getHeight() - 1; displayPixelInformation(xIndex,yIndex); } }); } /** * Create the pixel location panel * @param labelFont the font for the labels * @return the location panel */ public JPanel createLocationPanel(Font labelFont) { // create a location panel JPanel locationPanel = new JPanel(); locationPanel.setLayout(new FlowLayout()); Box hBox = Box.createHorizontalBox(); // create the labels xLabel = new JLabel("X:"); yLabel = new JLabel("Y:"); // create the text fields xValue = new JTextField(Integer.toString(xIndex + numberBase),6); xValue.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { displayPixelInformation(xValue.getText(),yValue.getText()); } }); yValue = new JTextField(Integer.toString(yIndex + numberBase),6); yValue.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { displayPixelInformation(xValue.getText(),yValue.getText()); } }); // set up the next and previous buttons setUpNextAndPreviousButtons(); // set up the font for the labels xLabel.setFont(labelFont); yLabel.setFont(labelFont); xValue.setFont(labelFont); yValue.setFont(labelFont); // add the items to the vertical box and the box to the panel hBox.add(Box.createHorizontalGlue()); hBox.add(xLabel); hBox.add(xPrevButton); hBox.add(xValue); hBox.add(xNextButton); hBox.add(Box.createHorizontalStrut(10)); hBox.add(yLabel); hBox.add(yPrevButton); hBox.add(yValue); hBox.add(yNextButton); locationPanel.add(hBox); hBox.add(Box.createHorizontalGlue()); return locationPanel; } /** * Create the color information panel * @param labelFont the font to use for labels * @return the color information panel */ private JPanel createColorInfoPanel(Font labelFont) { // create a color info panel JPanel colorInfoPanel = new JPanel(); colorInfoPanel.setLayout(new FlowLayout()); // get the pixel at the x and y Pixel pixel = new Pixel(picture,xIndex,yIndex); // create the labels rValue = new JLabel("R: " + pixel.getRed()); gValue = new JLabel("G: " + pixel.getGreen()); bValue = new JLabel("B: " + pixel.getBlue()); // create the sample color panel and label colorLabel = new JLabel("Color at location: "); colorPanel = new JPanel(); colorPanel.setBorder(new LineBorder(Color.black,1)); // set the color sample to the pixel color colorPanel.setBackground(pixel.getColor()); // set the font rValue.setFont(labelFont); gValue.setFont(labelFont); bValue.setFont(labelFont); colorLabel.setFont(labelFont); colorPanel.setPreferredSize(new Dimension(25,25)); // add items to the color information panel colorInfoPanel.add(rValue); colorInfoPanel.add(gValue); colorInfoPanel.add(bValue); colorInfoPanel.add(colorLabel); colorInfoPanel.add(colorPanel); return colorInfoPanel; } /** * Creates the North JPanel with all the pixel location * and color information */ private void createInfoPanel() { // create the info panel and set the layout JPanel infoPanel = new JPanel(); infoPanel.setLayout(new BorderLayout()); // create the font Font largerFont = new Font(infoPanel.getFont().getName(), infoPanel.getFont().getStyle(),14); // create the pixel location panel JPanel locationPanel = createLocationPanel(largerFont); // create the color informaiton panel JPanel colorInfoPanel = createColorInfoPanel(largerFont); // add the panels to the info panel infoPanel.add(BorderLayout.NORTH,locationPanel); infoPanel.add(BorderLayout.SOUTH,colorInfoPanel); // add the info panel pictureFrame.getContentPane().add(BorderLayout.NORTH,infoPanel); } /** * Method to check that the current position is in the viewing area and if * not scroll to center the current position if possible */ public void checkScroll() { // get the x and y position in pixels int xPos = (int) (xIndex * zoomFactor); int yPos = (int) (yIndex * zoomFactor); // only do this if the image is larger than normal if (zoomFactor > 1) { // get the rectangle that defines the current view JViewport viewport = scrollPane.getViewport(); Rectangle rect = viewport.getViewRect(); int rectMinX = (int) rect.getX(); int rectWidth = (int) rect.getWidth(); int rectMaxX = rectMinX + rectWidth - 1; int rectMinY = (int) rect.getY(); int rectHeight = (int) rect.getHeight(); int rectMaxY = rectMinY + rectHeight - 1; // get the maximum possible x and y index int maxIndexX = (int) (picture.getWidth() * zoomFactor) - rectWidth - 1; int maxIndexY = (int) (picture.getHeight() * zoomFactor) - rectHeight - 1; // calculate how to position the current position in the middle of the viewing // area int viewX = xPos - (int) (rectWidth / 2); int viewY = yPos - (int) (rectHeight / 2); // reposition the viewX and viewY if outside allowed values if (viewX < 0) viewX = 0; else if (viewX > maxIndexX) viewX = maxIndexX; if (viewY < 0) viewY = 0; else if (viewY > maxIndexY) viewY = maxIndexY; // move the viewport upper left point viewport.scrollRectToVisible(new Rectangle(viewX,viewY,rectWidth,rectHeight)); } } /** * Zooms in the on picture by scaling the image. * It is extremely memory intensive. * @param factor the amount to zoom by */ public void zoom(double factor) { // save the current zoom factor zoomFactor = factor; // calculate the new width and height and get an image that size int width = (int) (picture.getWidth()*zoomFactor); int height = (int) (picture.getHeight()*zoomFactor); BufferedImage bimg = picture.getBufferedImage(); // set the scroll image icon to the new image imageDisplay.setImage(bimg.getScaledInstance(width, height, Image.SCALE_DEFAULT)); imageDisplay.setCurrentX((int) (xIndex * zoomFactor)); imageDisplay.setCurrentY((int) (yIndex * zoomFactor)); imageDisplay.revalidate(); checkScroll(); // check if need to reposition scroll } /** * Repaints the image on the scrollpane. */ public void repaint() { pictureFrame.repaint(); } //****************************************// // Event Listeners // //****************************************// /** * Called when the mouse is dragged (button held down and moved) * @param e the mouse event */ public void mouseDragged(MouseEvent e) { displayPixelInformation(e); } /** * Method to check if the given x and y are in the picture * @param x the horiztonal value * @param y the vertical value * @return true if the x and y are in the picture and false otherwise */ private boolean isLocationInPicture(int x, int y) { boolean result = false; // the default is false if (x >= 0 && x < picture.getWidth() && y >= 0 && y < picture.getHeight()) result = true; return result; } /** * Method to display the pixel information from the passed x and y but * also converts x and y from strings * @param xString the x value as a string from the user * @param yString the y value as a string from the user */ public void displayPixelInformation(String xString, String yString) { int x = -1; int y = -1; try { x = Integer.parseInt(xString); x = x - numberBase; y = Integer.parseInt(yString); y = y - numberBase; } catch (Exception ex) { } if (x >= 0 && y >= 0) { displayPixelInformation(x,y); } } /** * Method to display pixel information for the passed x and y * @param pictureX the x value in the picture * @param pictureY the y value in the picture */ private void displayPixelInformation(int pictureX, int pictureY) { // check that this x and y is in range if (isLocationInPicture(pictureX, pictureY)) { // save the current x and y index xIndex = pictureX; yIndex = pictureY; // get the pixel at the x and y Pixel pixel = new Pixel(picture,xIndex,yIndex); // set the values based on the pixel xValue.setText(Integer.toString(xIndex + numberBase)); yValue.setText(Integer.toString(yIndex + numberBase)); rValue.setText("R: " + pixel.getRed()); gValue.setText("G: " + pixel.getGreen()); bValue.setText("B: " + pixel.getBlue()); colorPanel.setBackground(new Color(pixel.getRed(), pixel.getGreen(), pixel.getBlue())); } else { clearInformation(); } // notify the image display of the current x and y imageDisplay.setCurrentX((int) (xIndex * zoomFactor)); imageDisplay.setCurrentY((int) (yIndex * zoomFactor)); } /** * Method to display pixel information based on a mouse event * @param e a mouse event */ private void displayPixelInformation(MouseEvent e) { // get the cursor x and y int cursorX = e.getX(); int cursorY = e.getY(); // get the x and y in the original (not scaled image) int pictureX = (int) (cursorX / zoomFactor + numberBase); int pictureY = (int) (cursorY / zoomFactor + numberBase); // display the information for this x and y displayPixelInformation(pictureX,pictureY); } /** * Method to clear the labels and current color and reset the * current index to -1 */ private void clearInformation() { xValue.setText("N/A"); yValue.setText("N/A"); rValue.setText("R: N/A"); gValue.setText("G: N/A"); bValue.setText("B: N/A"); colorPanel.setBackground(Color.black); xIndex = -1; yIndex = -1; } /** * Method called when the mouse is moved with no buttons down * @param e the mouse event */ public void mouseMoved(MouseEvent e) {} /** * Method called when the mouse is clicked * @param e the mouse event */ public void mouseClicked(MouseEvent e) { displayPixelInformation(e); } /** * Method called when the mouse button is pushed down * @param e the mouse event */ public void mousePressed(MouseEvent e) { displayPixelInformation(e); } /** * Method called when the mouse button is released * @param e the mouse event */ public void mouseReleased(MouseEvent e) { } /** * Method called when the component is entered (mouse moves over it) * @param e the mouse event */ public void mouseEntered(MouseEvent e) { } /** * Method called when the mouse moves over the component * @param e the mouse event */ public void mouseExited(MouseEvent e) { } /** * Method to enable all menu commands */ private void enableZoomItems() { twentyFive.setEnabled(true); fifty.setEnabled(true); seventyFive.setEnabled(true); hundred.setEnabled(true); hundredFifty.setEnabled(true); twoHundred.setEnabled(true); fiveHundred.setEnabled(true); } /** * Controls the zoom menu bar * * @param a the ActionEvent */ public void actionPerformed(ActionEvent a) { if(a.getActionCommand().equals("Update")) { this.repaint(); } if(a.getActionCommand().equals("25%")) { this.zoom(.25); enableZoomItems(); twentyFive.setEnabled(false); } if(a.getActionCommand().equals("50%")) { this.zoom(.50); enableZoomItems(); fifty.setEnabled(false); } if(a.getActionCommand().equals("75%")) { this.zoom(.75); enableZoomItems(); seventyFive.setEnabled(false); } if(a.getActionCommand().equals("100%")) { this.zoom(1.0); enableZoomItems(); hundred.setEnabled(false); } if(a.getActionCommand().equals("150%")) { this.zoom(1.5); enableZoomItems(); hundredFifty.setEnabled(false); } if(a.getActionCommand().equals("200%")) { this.zoom(2.0); enableZoomItems(); twoHundred.setEnabled(false); } if(a.getActionCommand().equals("500%")) { this.zoom(5.0); enableZoomItems(); fiveHundred.setEnabled(false); } } /** * Test Main. It will ask you to pick a file and then show it */ public static void main( String args[]) { Picture p = new Picture(FileChooser.pickAFile()); PictureExplorer test = new PictureExplorer(p); } /** * Class for establishing the focus for the textfields */ private class PictureExplorerFocusTraversalPolicy extends FocusTraversalPolicy { /** * Method to get the next component for focus */ public Component getComponentAfter(Container focusCycleRoot, Component aComponent) { if (aComponent.equals(xValue)) return yValue; else return xValue; } /** * Method to get the previous component for focus */ public Component getComponentBefore(Container focusCycleRoot, Component aComponent) { if (aComponent.equals(xValue)) return yValue; else return xValue; } public Component getDefaultComponent(Container focusCycleRoot) { return xValue; } public Component getLastComponent(Container focusCycleRoot) { return yValue; } public Component getFirstComponent(Container focusCycleRoot) { return xValue; } } } |
File: bb.htm | [Next] | [Prev] |