2012-10-24 70 views
4

好的,我一直在搜索和谷歌搜索了很多年,這讓我瘋狂。 (請記住,這是從大學的代碼開始的)。Java paint問題

任何幫助將大規模讚賞!因爲我看起來有一個心理障礙,當涉及到Java圖形:(

問題是標籤的圖像,但我有問題的一半圖像因各種原因丟失,除非我移動框架然後回來,同樣,如果我嘗試刪除在BufferedImage上繪製的「標籤」,我必須在Jframe上移動才能看到結果

最後,當JOptionPane彈出要求標籤名稱,它這樣做關閉時:

獲得的圖像後 https://docs.google.com/document/d/1I5rFH23a75IHB6twTu1dPRwmRt-By1sIUvDvI6FE_OY/edit

package hci; 

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

/** 
* Deals with the label tools 
*/ 
public class LabelToolGUI extends JPanel implements ActionListener { 

     JButton newButton = new JButton("New"); 
     JButton deleteButton = new JButton("Delete"); 
     JButton editButton = new JButton("Edit"); 
     JButton undoButton = new JButton("Undo"); 
     JComboBox labelsBox = new JComboBox(); 

    String saveIcon = "./images/icons/save.jpg"; 
    String deleteIcon = "./images/icons/delete.jpg"; 
    String openIcon = "./images/icons/open.jpg"; 
    String newIcon = "./images/icons/new.jpg"; 
    String helpIcon = "./images/icons/help.jpg"; 
    String labelsIcon = "./images/icons/help.jpg"; 
    String fname = ""; 
    String fnameURL = ""; 

    public LabelToolGUI() { 
     super(); 
     newButton.addActionListener(this); 
     deleteButton.addActionListener(this); 
     editButton.addActionListener(this); 
     undoButton.addActionListener(this); 

     setLayout(new BorderLayout()); 
     setBorder(BorderFactory.createTitledBorder("Label tools")); 

     add(newButton, BorderLayout.WEST); 
     add(deleteButton, BorderLayout.EAST); 
     add(editButton, BorderLayout.CENTER); 
     add(labelsBox, BorderLayout.NORTH); 
     add(undoButton, BorderLayout.SOUTH); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     Object src = e.getSource(); 
     if(src == newButton) { 
      String labelName = JOptionPane.showInputDialog("Please input a value"); 
      ImageLabeller.addNewPolygon(labelName); 
      labelsBox.addItem(labelName); 
     } else if(src == deleteButton) { 
      String toDelete = labelsBox.getSelectedItem().toString(); 
      System.out.println("Deleting " + toDelete); 
      labelsBox.removeItem(labelsBox.getSelectedItem()); 
      ImageLabeller.removeLabel(toDelete); 
     } else if(src == undoButton) { 
      ImageLabeller.undo(); 
      ImageLabeller.imagePanel.repaint(); 
     } 
    } 
} 

package hci; 

import javax.swing.*; 

import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.KeyEvent; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 

/** 
* Main class of the program - handles display of the main window 
* @author Michal 
* 
*/ 
public class ImageLabeller extends JFrame implements ActionListener { 
    /** 
    * some java stuff to get rid of warnings 
    */ 
    private static final long serialVersionUID = 1L; 

    /** 
    * main window panel 
    */ 
    JPanel appPanel = null; 

    /** 
    * toolbox - put all buttons and stuff here! 
    */ 
    JPanel toolboxPanel = null; 


    /** 
    * image panel - displays image and editing area 
    */ 
    static ImagePanel imagePanel = null; 

    /** 
    * handles New Object button action 
    */ 
    public static void addNewPolygon(String labelName) { 
     imagePanel.addNewPolygon(labelName); 
    } 

    public static void removeLabel(String labelName) { 
     LabelHandler.deleteLabel(labelName); 
    } 

    /** 
    * Removes last point added to the label. 
    */ 
    public static void undo() { 
     imagePanel.currentLabel.removeLast(); 
    } 

    /*@Override 
    public void paint(Graphics g) { 
     super.paint(g); 
     imagePanel.paint(g); //update image panel 
    } */ 

    /** 
    * sets up application window 
    * @param imageFilename image to be loaded for editing 
    * @throws Exception 
    */ 
    public void setupGUI(String imageFilename) throws Exception { 
     this.addWindowListener(new WindowAdapter() { 
      public void windowClosing(WindowEvent event) { 
       //here we exit the program (maybe we should ask if the user really wants to do it?) 
       //maybe we also want to store the polygons somewhere? and read them next time 
       System.out.println("Bye bye!"); 
       System.exit(0); 
      } 
     }); 

     //setup main window panel 
     appPanel = new JPanel(); 
     this.setLayout(new BoxLayout(appPanel, BoxLayout.X_AXIS)); 
     this.setContentPane(appPanel); 

     //Create and set up the image panel. 
     imagePanel = new ImagePanel(imageFilename); 
     imagePanel.setOpaque(true); //content panes must be opaque 

      appPanel.add(imagePanel); 

     //add toolbox to window 
     appPanel.add(new LabelToolGUI()); 

     //display all the stuff 
     this.pack(); 
      this.setVisible(true); 
    } 


    /** 
    * Runs the program 
    * @param argv path to an image 
    */ 
    public static void main(String argv[]) { 
     try { 
      //create a window and display the image 
      ImageLabeller window = new ImageLabeller(); 
      window.setupGUI(argv[0]); 
     } catch (Exception e) { 
      System.err.println("Image: " + argv[0]); 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("Action clicked"); 
     imagePanel.paint(imagePanel.getGraphics()); 
    } 
} 

package hci; 

import javax.imageio.ImageIO; 
import javax.swing.JPanel; 

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Image; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.util.ArrayList; 

import hci.utils.*; 

/** 
* Handles image editing panel 
* @author Michal 
* 
*/ 
public class ImagePanel extends JPanel implements MouseListener { 
    /** 
    * some java stuff to get rid of warnings 
    */ 
    private static final long serialVersionUID = 1L; 

    /** 
    * image to be tagged 
    */ 
    BufferedImage image = null; 

    /** 
    * list of current polygon's vertices 
    */ 
    Label currentLabel = null; 

    /** 
    * default constructor, sets up the window properties 
    */ 
    public ImagePanel() { 
     currentLabel = new Label(); 

     this.setVisible(true); 

     Dimension panelSize = new Dimension(800, 600); 
     this.setSize(panelSize); 
     this.setMinimumSize(panelSize); 
     this.setPreferredSize(panelSize); 
     this.setMaximumSize(panelSize); 

     addMouseListener(this); 
    } 

    /** 
    * extended constructor - loads image to be labelled 
    * @param imageName - path to image 
    * @throws Exception if error loading the image 
    */ 
    public ImagePanel(String imageName) throws Exception{ 
     this(); 
     image = ImageIO.read(new File(imageName)); 
     if (image.getWidth() > 800 || image.getHeight() > 600) { 
      int newWidth = image.getWidth() > 800 ? 800 : (image.getWidth() * 600)/image.getHeight(); 
      int newHeight = image.getHeight() > 600 ? 600 : (image.getHeight() * 800)/image.getWidth(); 
      System.out.println("SCALING TO " + newWidth + "x" + newHeight); 
      Image scaledImage = image.getScaledInstance(newWidth, newHeight, Image.SCALE_FAST); 
      image = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); 
      image.getGraphics().drawImage(scaledImage, 0, 0, this); 
     } 
    } 

    /** 
    * Displays the image 
    */ 
    public void ShowImage() { 
     Graphics g = this.getGraphics(); 

     if (image != null) { 
      g.drawImage(image, 0, 0, null); 
     } 
    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     //display iamge 
     ShowImage(); 

     //display all the completed polygons 
     for(Label l : LabelHandler.labels) { 
      drawLabel(l); 
      finishPolygon(l); 
     } 

     //display current polygon 
     drawLabel(currentLabel); 
    } 

    /** 
    * displays a polygon without last stroke 
    * @param l label to be displayed 
    */ 
    public void drawLabel(Label l) { 
     Graphics2D g = (Graphics2D)this.getGraphics(); 
     g.setColor(Color.GREEN); 
     for(int i = 0; i < l.size(); i++) { 
      Point currentVertex = l.getPoint(i); 
      if (i != 0) { 
       Point prevVertex = l.getPoint(i - 1); 
       g.drawLine(prevVertex.getX(), prevVertex.getY(), currentVertex.getX(), currentVertex.getY()); 
      } 
      g.fillOval(currentVertex.getX() - 5, currentVertex.getY() - 5, 10, 10); 
     } 
    } 

    /** 
    * displays last stroke of the polygon (arch between the last and first vertices) 
    * @param l label to be finished 
    */ 
    public void finishPolygon(Label l) { 
     //if there are less than 3 vertices than nothing to be completed 
     if (l.size() >= 3) { 
      Point firstVertex = l.getPoint(0); 
      Point lastVertex = l.getPoint(l.size() - 1); 

      Graphics2D g = (Graphics2D)this.getGraphics(); 
      g.setColor(Color.GREEN); 
      g.drawLine(firstVertex.getX(), firstVertex.getY(), lastVertex.getX(), lastVertex.getY()); 
     } 
    } 

    /** 
    * moves current polygon to the list of polygons and makes pace for a new one 
    */ 
    public void addNewPolygon(String labelName) { 
     //finish the current polygon if any 
     if (currentLabel != null) { 
      finishPolygon(currentLabel); 
      LabelHandler.addLabel(currentLabel); 
     } 

     currentLabel = new Label(labelName); 
    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
     int x = e.getX(); 
     int y = e.getY(); 

     //check if the cursos withing image area 
     if (x > image.getWidth() || y > image.getHeight()) { 
      //if not do nothing 
      return; 
     } 

     Graphics2D g = (Graphics2D)this.getGraphics(); 

     //if the left button than we will add a vertex to poly 
     if (e.getButton() == MouseEvent.BUTTON1) { 
      g.setColor(Color.GREEN); 
      if (currentLabel.size() != 0) { 
       Point lastVertex = currentLabel.getPoint(currentLabel.size() - 1); 
       g.drawLine(lastVertex.getX(), lastVertex.getY(), x, y); 
      } 
      g.fillOval(x-5,y-5,10,10); 

      currentLabel.addPoint(new Point(x,y)); 
      System.out.println(x + " " + y); 
     } 
    } 

    @Override 
    public void mouseEntered(MouseEvent arg0) { 
    } 

    @Override 
    public void mouseExited(MouseEvent arg0) { 
    } 

    @Override 
    public void mousePressed(MouseEvent arg0) { 
    } 

    @Override 
    public void mouseReleased(MouseEvent arg0) { 
    } 

} 
+0

*請記住,這是以大學代碼開始*這是否意味着您的問題是基於作業? –

+0

他們給出的基本代碼,你打算建立它。作業本身不是與油漆相關的,而是與我完全沒有問題的GUI設計有關。 但油漆問題令人討厭 - 我是一個完美主義者。 – LifeQuestioner

回答

4

不要使用getGraphics()爲你的畫,因爲它是下次上重繪回收臨時緩衝區。做您在paintComponent()畫,並根據需要調用repaint()

也不要叫paint()手動。(即:imagePanel.paint(imagePanel.getGraphics());

有關更多信息,請參見Performing Custom Painting另見Painting in AWT and Swing

+0

非常感謝您的回覆。 我不確定除getGraphics之外還有其他什麼用法?不過,我會先閱讀你給我的鏈接,因爲他們看起來很好(我認爲我的谷歌技能是垃圾,因爲我從來沒有遇到過第一個)。 – LifeQuestioner

+0

@Taios當然有'getGraphics()'適用的情況。比如在繪製一個'BufferedImage'時,返回的'getGraphics()'在你的控制之下。你樣本中的ImagePanel構造函數做類似的事情。 – tenorsax

2

通過ImagePanel.paintComponent替換if (image != null) g.drawImage(image, 0, 0, this);ShowImage();

方面g由擺動初始化的設備,你不「噸有通過getGraphics()獲得另一個。