JButton只出现在鼠标上方

时间:2015-02-23 19:09:14

标签: java jpanel jbutton

我遇到的问题是,如果我将鼠标移动到按钮所在的位置,我的JButton才会出现。我尝试了很多解决方法,比如使用paintComponents()而不是paint(),使用repaint(),setVisible()等等,但没有任何帮助。我确定问题是TextArea,如果我发表评论:pnlBackground.add(txt);,程序启动时会弹出Button,但TextArea不显示。有什么想法吗?

public class MediGraph extends JFrame {

private JPanel pnlBackground;
private JPanel pnlGraph;
private JTextArea txt;
private JButton btnFileChooser;
private JFileChooser fcFiler;
public static String fileName = "Langzeitblutdruck_PID34567.txt";

public MediGraph(){
    //JFrame
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(new Dimension(900,420));
    setLocationRelativeTo(null);
    setResizable(false);
    setTitle("MediGraph");
    //pnlBackground
    pnlBackground = new JPanel();
    pnlBackground.setLayout(null);
    pnlBackground.setBounds(0, 0, 650, 420);
    //pnlGraph
    pnlGraph = new JPanel();
    pnlGraph.setLayout(null);
    pnlGraph.setBounds(0, 0, 650, 370);
    pnlBackground.add(pnlGraph);
    //JTextArea
    txt = new JTextArea();
    txt.setBounds(620, 5, 270, 305);
    //fcFiler
    fcFiler = new JFileChooser();
    //btnFileChooser
    btnFileChooser = new JButton("Datei einlesen");
    btnFileChooser.setBounds(250, 335, 135, 30);
    btnFileChooser.addActionListener(new ActionListener(){
        @Override
        public void actionPerformed(ActionEvent e) {
            fcFiler.showOpenDialog(btnFileChooser);
            if(fcFiler.getSelectedFile() != null){
                fileName = fcFiler.getSelectedFile().getAbsolutePath();
                System.out.println(fileName);
                repaint();
            }
        }
    });

    pnlBackground.add(txt);
    pnlBackground.add(btnFileChooser);  
    add(pnlBackground);
    setVisible(true);

}

public void paint(Graphics g){

    g = this.pnlGraph.getGraphics();
    Color HeretsuEnt = new Color (204, 0, 0); //Farben für Achsen, Firmenlogo und Systole
    Color Greeen = new Color (0, 195, 0);
    Color Indigo = new Color (128,0,128);
    g.clearRect(0, 0, 600, 700);
    //x und y Achse
    g.setColor (Indigo);
    g.drawLine (27, 15, 27, 300);
    g.drawLine (27, 300, 600, 300);
    // Linien der Achsenabschnitte
    for (int i = 27; i < 600; i += 20) {
      g.drawLine (i, 298, i, 302);
      if(i < 300)
      g.drawLine (24, i, 30, i);
    }
    //Beschriftung Abschnitte
            //y-Achse
    g.drawString("100", 5, 213);
    g.drawString("200", 5, 113);
    g.drawString("300", 5, 13);
    g.drawString("Werte",35, 23);
            //x-Achse
    g.drawString("5",  125, 314);
    g.drawString("10", 225, 314);
    g.drawString("15", 325, 314);
    g.drawString("20", 425, 314);
    g.drawString("25", 525, 314);
    g.drawString("in Stunden",548, 319);

    // Linen für die Pfeilspitzen 
    g.drawLine (605, 300, 595, 295);
    g.drawLine (605, 300, 595, 305);
    g.drawLine (27, 14, 22, 22);
    g.drawLine (27, 14, 32, 22);

    //Firmenlogo :)
    g.setFont(new Font("Times New Roman", Font.ITALIC, 20));
    g.setColor(HeretsuEnt);
    g.drawString ("Heretsu Enterprises",400, 355);

    //Legende
    g.setFont(new Font("Arial", Font.LAYOUT_LEFT_TO_RIGHT, 15));
    g.setColor(Color.RED);
    g.drawLine(100, 320, 120, 320);
    g.drawString("Puls", 30, 325);

    g.setColor(Color.BLUE);
    g.drawLine(100, 340, 120, 340);
    g.drawString("Diastole", 30, 345);

    g.setColor(Greeen);
    g.drawLine(100, 360, 120, 360);
    g.drawString("Systole", 30, 365);

    //Graphen
    Untersuchung untersuchung = new Untersuchung();
    Auslesen.lesen(fileName);
    ArrayList messwerte = untersuchung.getMesswerte();
    g.setColor(HeretsuEnt);
    g.drawString(fileName,200, 15);

    String ausgabe =  "  Datum   "+"      Uhrzeit   "+"    Systole   "+"Diastole   "+"Puls   "+"\n ";
    for(int i = 0;i < messwerte.size();i++){
      ausgabe += "" +""+((Messwert)messwerte.get(i)).getDatum() + "    " + ((Messwert)messwerte.get(i)).getUhrzeit()
              + "         " + ((Messwert)messwerte.get(i)).getSystole() + "          " + ((Messwert)messwerte.get(i)).getDiastole() + "          " + ((Messwert)messwerte.get(i)).getPuls() +"\n ";

    }   
    txt.setText(ausgabe);
    for (int j = 4; j < messwerte.size() - 1; j++) {
      g.setColor(Color.RED);
      g.drawLine((j*27/4),(-300 + ((Messwert)messwerte.get(j)).getPuls())/-1,(j+1)*27/4, (-300 + ((Messwert)messwerte.get(j+1)).getPuls())/-1);
      g.setColor(Color.BLUE);
      g.drawLine((j*27/4),(-300 + ((Messwert)messwerte.get(j)).getDiastole())/-1,(j+1)*27/4,(-300 + ((Messwert)messwerte.get(j+1)).getDiastole())/-1); 
      g.setColor(Greeen);
      g.drawLine((j*27/4),(-300 + ((Messwert)messwerte.get(j)).getSystole())/-1,(j+1)*27/4,(-300 + ((Messwert)messwerte.get(j+1)).getSystole())/-1); 
    }

}

public static void main(String[] args) {
    new MediGraph();

}}

1 个答案:

答案 0 :(得分:1)

你有很多问题......

让我们从setLayout(null);

开始

避免使用null布局,像素完美布局是现代ui设计中的一种幻觉。影响组件个体大小的因素太多,您无法控制。 Swing旨在与布局管理器一起工作,放弃这些将导致问题和问题的终结,您将花费越来越多的时间来纠正

虽然它看起来像是一个好主意,但事实并非如此,你最终会在不同的计算机上出现几乎随机出现的小问题。布局管理API旨在克服这些问题并使您的生活更轻松。

接下来,画画......

public void paint(Graphics g){

    g = this.pnlGraph.getGraphics();

你覆盖paint的{​​{1}},这本身不推荐,但是你没有调用JFrame,这阻止了框架不仅仅是绘画本身,​​而是也是任何儿童成分。

现在,如果这还不够糟糕,那么您可以获取对另一个组件的super.paint上下文的引用,并在框架的Graphics方法中绘制IT。绘画应仅绘制CURRENT组件...

永远不要使用paint,严重的是,这不是在Swing中完成绘画的方式。它可以返回getGraphics,你绘制的任何东西都将在组件的下一个绘制周期中被销毁。组件可以与其容器分开绘制,因此容器可能不知道它的子组件由于某种原因已经更新(例如,当鼠标进入或退出时)

然后......在框架的null方法中,您调用paint ...

您绝不应该在任何txt.setText(ausgabe);方法中直接或间接更新组件或任何子组件的状态。这将导致无限循环的重绘请求,最终会占用您的CPU周期并使您的程序无法使用。

我建议你回到基础并看看:

我还建议:

  • 您使用了适当的布局
  • 为图表创建自定义组件,从paint延伸并覆盖它的JPanel方法。在那里,您需要执行仅渲染图形所需的绘制操作。另外,请确保您没有打破油漆链并确保在执行任何自定义绘画之前致电paintComponent
  • 不覆盖super.paintComponent
  • paint