在我的JPanel中绘制调用" main"中的函数。

时间:2014-05-22 17:43:37

标签: java swing graphics awt

我在课堂上有一个JAVA语言的信息项目,并且它被评为从高中毕业。

顺便说一句,我的程序包括在JPanel中绘制几何形式,但是我不知道如何在我的主程序中放置绘制数字的功能,如drawSquare(x,y,length) 。目前程序显示此窗口(它是我的JPanel里面的JFrame):

http://i.imgur.com/YetG3VB.png

我有一个方法readClick(),它给了Point点坐标point.x和point.y在框架中但是我不知道在我的主要部分,我可以怎么做来调用图形绘图。 "我的问题是我想在我的主程序中添加类似

的内容
Point clic; 
clic= Fenetre.readClick() ; // I have this method which wait me to clic on the frame  
x = clic.x ;    //and give to point the coordonates 
y= clic.y;    // point.x && point.y
clic = Fenetre.readClick();
a = clic.x ;
b = clic.y ;
"Function which draws rectangle for example"(x,y,a,b);
//It's this fonction I want to create and
// I want it to draw the rectangle in the JPanel 

但我不知道如何制作在JPanel中添加绘图的功能"

我的主要计划:

public class Geogebra  {
   @SuppressWarnings("unused")
     public static void main(String args[]){
    Fenetre fen = new Fenetre();
     }}

我的窗口类:

import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.concurrent.SynchronousQueue;
import javax.swing.JFrame;

@SuppressWarnings({ "unused", "serial" })
public class Fenetre extends JFrame {

static Panneau component = null;
private final static SynchronousQueue<MouseEvent> clicks = new SynchronousQueue<MouseEvent>();
public Fenetre(){
    JFrame frame = new JFrame();
      component = new Panneau();    
    frame.setTitle("ISNOGEBRA");
    frame.setSize(900, 700); // Taille initiale de la fenetre : 900 * 700
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
    frame.setContentPane(component);
    frame.setVisible(true);   
    component.addMouseListener( new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            clicks.offer(e);
        }
    });


}
public static MouseEvent readMouse() {
    try {
    return clicks.take();
    }
    catch (InterruptedException e) {
    throw new AssertionError();
    }
    }
 public static Point readClick() {
        return readMouse().getPoint();
        }

}

我的JPanel类(两个类Mathwrapper和Menu只绘制界面,如果需要我会显示它们,但它真的很长):

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.swing.JPanel;

@SuppressWarnings({ "serial", "unused" })
public class Panneau extends JPanel implements MouseListener {
Menu menu;
MathWrapper mw;

public Panneau(){
    super();
    this.setBackground(Color.WHITE);
    menu = new Menu(20, 20);
    mw = MathWrapper.getInstance(0, 80);
    this.setOpaque(true);
    this.addMouseListener(this);        
}


@Override 
public void paintComponent(Graphics g){
    menu.draw(g);
    mw.draw(g);
    }

public void mouseClicked(MouseEvent e) {
    //That shows a blue square behind the icon in the menu I click on 
    //and draws a black one on the one which was selected 

    if((e.getX() > 20  && e.getX() < 60) && (e.getY()) > 20 && e.getY() < 60){
        menu.btns[menu.activeTool].toggleClicked();
        menu.btns[0].toggleClicked();
        menu.activeTool = 0;
    }else if((e.getX() > 80  && e.getX() < 120) && (e.getY()) > 20 && e.getY() < 60){
        menu.btns[menu.activeTool].toggleClicked();
        menu.btns[1].toggleClicked();
        menu.activeTool = 1;
    }else if((e.getX() > 140  && e.getX() < 180) && (e.getY()) > 20 && e.getY() < 60){
        menu.btns[menu.activeTool].toggleClicked();
        menu.btns[2].toggleClicked();
        menu.activeTool = 2;
    }else if((e.getX() > 200  && e.getX() < 240) && (e.getY()) > 20 && e.getY() < 60){
        menu.btns[menu.activeTool].toggleClicked();
        menu.btns[3].toggleClicked();
        menu.activeTool = 3;
    }else if((e.getX() > 260  && e.getX() < 300) && (e.getY()) > 20 && e.getY() < 60){
        menu.btns[menu.activeTool].toggleClicked();
        menu.btns[4].toggleClicked();
        menu.activeTool = 4;
    }
    mw.setActiveTool(menu.activeTool);
    this.repaint();
}

public void mouseEntered(MouseEvent e) {

}

public void mouseExited(MouseEvent e) {


}

public void mousePressed(MouseEvent e) {

}

public void mouseReleased(MouseEvent e) {

}

}

请帮助我,我已经阅读了有关JPanel和绘图的文件,但我仍然不明白..

2 个答案:

答案 0 :(得分:1)

如果我理解你的问题,你基本上想要一些你可以

的功能
  • 等待用户互动并获取相关信息
  • 在窗口画一些东西

(我现在忽略了你想从主方法中做到这一点,因为我很确定你会很高兴从另一种方法中做到这一点)

基本上你在这个项目中面临两个障碍:

  • 在大多数窗口系统中绘图是事件驱动的,i。即如果用户将窗口置于前面,则必须知道如何绘制其当前状态
  • 用户互动也是事件驱动的,i。即当用户点击时,您将收到回调。

第一个障碍很容易解决:在你的UI代码和函数都可以访问的地方创建一个BufferedImage,并在其中绘制。 (BufferedImage有一个createGraphics方法,可以用来在图像的缓冲区内绘制)。然后,只要有人将窗口置于前台,paintComponent方法就会绘制图像。

第二个障碍有点困难。基本上你需要线程和同步。以前使用waitnotify以及synchronized调用Java 1.4会进行大量调整,但是从Java 1.5开始,同步(对于这种特殊情况)可以由{{ 1}}类。因此,您的UI代码等待(使用MouseListener)鼠标单击并将坐标(作为java.awt.Point)添加到BlockingQueue,并且您的UI代码只需在需要时等待下一个点。你仍然会有一些使用多线程应用程序的经验(所以你应该知道如何启动一个Thread并且Thread不能直接与UI交互),所以根据你对Java的经验,这可能是一个陡峭的学习曲线 - 但肯定可行的。

编辑:我看到你已经在为鼠标事件使用了某种同步,所以你可能只需要启动一个线程并绘制到BufferedImage而不是真正的窗口本身

EDIT2 :这是一个非常简化的示例,向您展示如何从第二个线程绘制到BlockingQueue。它将从控制台(标准输入)请求坐标和颜色,并将它们绘制到图像中,该图像将显示在JPanel中。您可以将此示例与您已经拥有的移动鼠标位置等结合起来。

BufferedImage

答案 1 :(得分:0)

您必须设置JFrame的可见性。在你的主要课程中试试这个。

public class Geogebra  {
   @SuppressWarnings("unused")
     public static void main(String args[]){
    Fenetre fen = new Fenetre();
    fen.setVisible(true);
     }}