如何在 JFrame 上显示 Graphics2D 对象

How to display Graphics2D object on JFrame

这是我第一次尝试构建 GUI,我陷入了僵局,我似乎无法找到解决方案。目前我已经设置了部分 GUI,但我想插入我在另一个 class 上创建的图形,但是,我不确定如何 link 它与我当前的 JFrame。我可以让它作为一个单独的实体工作,但不能一起工作。

主显示器Class:

public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(MainDisplay.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new MainDisplay().setVisible(true);
        }

    });
     float LvBTC;
    float LvLTC;
    float LvETH;

    float[] HBTC;
    float[] HLTC;
    float[] HETH;

    float CurETH;
    float CurBTC;
    float CurLTC;

    WebScraper WS1 = new WebScraper();
    LvBTC = WS1.LvScrapeBTC();
    LvLTC = WS1.LvScrapeLTC();
    LvETH = WS1.LvScrapeETH();

    HBTC = WS1.HScrapeBTC();
    HLTC = WS1.HScrapeLTC();
    HETH = WS1.HScrapeETH(); 

    System.out.println("Bitcoin's Current Price is: $"+LvBTC);
    System.out.println("Litecoin's Current Price is: $"+LvLTC);
    System.out.println("Ethereum's Current Price is: $"+LvETH);
    Graph G1 = new Graph();
    G1.CurrentValues(HBTC);

    for (int i = 0; 5 > i;) {
        System.out.println("Day " + (i + 1) + ": $" + G1.CurValues[i]);
        i++;
    }

   System.out.println("Index of largest value: " + G1.IndexLarge(G1.CurValues));
    System.out.println("Index of smallest value: " + G1.IndexSmall(G1.CurValues));

    Graph Graphing = new Graph();



}

图表Class:

package comsci_ia;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.JFrame;

public class Graph extends JFrame {

int IndexL;
int IndexS;
int DistanceDay1;
int DistanceDay2;
int DistanceDay3;
int DistanceDay4;
int DistanceDay5;
float[] CurValues = new float[5];

ArrayList<Point> points = new ArrayList<>();

public float[] CurrentValues(float[] array) {
    DatabaseBrowser DB1 = new DatabaseBrowser();
    WebScraper WS1 = new WebScraper();

    float[] HBTC = WS1.HScrapeBTC();
    float[] HETH = WS1.HScrapeETH();
    float[] HLTC = WS1.HScrapeLTC();

    float CurHold = 0;

    boolean BTCCheck = false;
    BTCCheck = Arrays.equals(HBTC, array);

    boolean LTCCheck = false;
    LTCCheck = Arrays.equals(HLTC, array);

    boolean ETHCheck = false;
    ETHCheck = Arrays.equals(HETH, array);

    if (BTCCheck == true) {
        CurHold = DB1.RetriveBTC();
    }

    if (LTCCheck == true) {
        CurHold = DB1.RetriveLTC();
    }

    if (ETHCheck == true) {
        CurHold = DB1.RetriveETH();
    }

    float pick;

    for (int i = 0; 5 > i;) {
        for (int z = 0; z < array.length; z++) {
            pick = array[z];
            pick = pick * CurHold;
            CurValues[i] = pick;
            i++;
        }

    }
    return CurValues;
}

public int IndexLarge(float[] array) {
    float temp = 0;
    for (int i = 0; 5 > i;) { //Cycles through ArrayList and replaces temp with the Largest value
        if (array[i] > temp) {
            temp = array[i];
        }
        i++;
    }
    int IndexCheck = 0; //Searches and records the index of "temp" value (Largest value in array)
    for (IndexCheck = 0; 5 > IndexCheck;) {
        if (array[IndexCheck] == temp) {
            break;
        }
        IndexCheck++;
    }
    IndexL = IndexCheck;
    return IndexL;
}

public int IndexSmall(float[] array) {
    float temp = 1000000;
    for (int i = 0; 5 > i;) { //Cycles through ArrayList and replaces temp with the smallest value
        if (array[i] < temp) {
            temp = array[i];
        }
        i++;
    }
    int IndexCheck = 0; //Searches and records the index of "temp" value (smallest value in array)
    for (IndexCheck = 0; 5 > IndexCheck;) {
        if (array[IndexCheck] == temp) {
            break;
        }
        IndexCheck++;
    }
    IndexS = IndexCheck;
    return IndexS;
}

public void Plotter(float[] array) { 
  /*  int DayRefL = IndexL + 1;
    int DayRefS = IndexS + 1; */
    float ValRange;
    float ValPx;

    points = null;

    ValRange = array[IndexL] - array[IndexS];
    ValPx = (300f/ ValRange); //Number is the pixel distance between highest and lowest values
    DistanceDay1 = (int) ((int) 50 + ((array[IndexL] - array[0]) * ValPx));
    DistanceDay2 = (int) ((int) 50 + ((array[IndexL] - array[1]) * ValPx));
    DistanceDay3 = (int) ((int) 50 + ((array[IndexL] - array[2]) * ValPx));
    DistanceDay4 = (int) ((int) 50 + ((array[IndexL] - array[3]) * ValPx));
    DistanceDay5 = (int) ((int) 50 + ((array[IndexL] - array[4]) * ValPx));

}
public void paintComponent(Graphics g) {

    Graphics2D g2 = (Graphics2D) g;

    int DotSize = 10;

    int width = g2.getFontMetrics().stringWidth("Today");
    int middle = width / 2;

    g2.setColor(Color.BLACK);
    /* g2.drawLine(10, 10, 10, 410); //Frame Boundaries
    g2.drawLine(410, 10, 10, 10); //Frame Boundaries
    g2.drawLine(410, 10, 410, 410); //Frame Boundaries
    g2.drawLine(410, 410, 10, 410); //Frame Boundaries */

    //Axis
    g2.drawLine(30, 30, 30, 370);
    g2.drawLine(370, 370, 30, 370);

    //Points & Connections
    PlotPoints(g2, 98, DistanceDay1, DotSize);
    g2.drawLine(98, DistanceDay1, 166, DistanceDay2);
    PlotPoints(g2, 166, DistanceDay2, DotSize);
    g2.drawLine(166, DistanceDay2, 234, DistanceDay3);
    PlotPoints(g2, 234, DistanceDay3, DotSize);
    g2.drawLine(234, DistanceDay3, 302, DistanceDay4);
    PlotPoints(g2, 302, DistanceDay4, DotSize);
    g2.drawLine(302, DistanceDay4, 370, DistanceDay5);
    PlotPoints(g2, 370, DistanceDay5, DotSize);

    //Labels
    g2.drawString("Today", 370 - middle, 390);
  /*  g2.drawString("Test", 98 - middle, 40);
    g2.drawString("Test", 146, 25); */

}

private void PlotPoints(Graphics2D g, int x, int y, int r) {
    x = x - (r / 2);
    y = y - (r / 2);
    g.fillOval(x, y, r, r);
}

}

如果我 运行 图表 class 作为一个单独的实体,它将导致:Graph pop-up

这是 Graph 代码的单独版本,其中将弹出一个框架来显示图表:

package graphing;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Graphing extends JPanel {

@Override
public void paintComponent(Graphics g) {

    Graphics2D g2 = (Graphics2D) g;

    int DotSize = 10;

    int width = g2.getFontMetrics().stringWidth("Test");
    int middle = width / 2;

    g2.setColor(Color.BLACK);
    g2.drawLine(10, 10, 10, 390); //Frame Boundaries
    g2.drawLine(390, 10, 10, 10); //Frame Boundaries
    g2.drawLine(390, 10, 390, 390); //Frame Boundaries
    g2.drawLine(390, 390, 10, 390); //Frame Boundaries

    //Axis
    g2.drawLine(30, 30, 30, 370);
    g2.drawLine(370, 370, 30, 370);

    //Points & Connections
    PlotPoints(g2, 98, 55, DotSize);
    g2.drawLine(98, 55, 166, 40);
    PlotPoints(g2, 166, 40, DotSize);
    g2.drawLine(166, 40, 234, 100);
    PlotPoints(g2, 234, 100, DotSize);
    g2.drawLine(234, 100, 302, 332);
    PlotPoints(g2, 302, 332, DotSize);
    g2.drawLine(302, 332, 370, 40);
    PlotPoints(g2, 370, 40, DotSize);

    //Labels
    g2.drawString("Test", 98 - middle, 40);
    g2.drawString("Test", 146, 25);

}

private void PlotPoints(Graphics2D g, int x, int y, int r) {
    x = x - (r / 2);
    y = y - (r / 2);
    g.fillOval(x, y, r, r);
}

public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setSize(420, 420);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Graphing app = new Graphing();

    frame.setContentPane(app);

    frame.setVisible(true);
    frame.invalidate();
}

}

所以,我的直接问题是,您正在从 JFrame 扩展,这不是一个好主意,因为这将 UI 锁定在单个用例中(这不容易重新-可用)

我的第二个问题是,你在JFrame中创建了一个名为paintComponent的方法,但是由于JFrame没有使用这种绘画风格,所以它永远不会被调用

所以,我要做的第一件事就是更改 Graph,使其从 JPanel 扩展为...

public class Graph extends JPanel {
    //...

然后我会更新您的 paintComponent 以便它正确支持绘画过程...

@Overrride
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    //...

现在,下一个问题是,您将需要提供一些调整大小的提示,以便您添加它的容器的布局管理器对如何最好地布局组件有一些想法...

@Override
public Dimension getPreferredSize() {
    // I've not been through your code in detail
    // so I've not calculated what the actual
    // preferred size might be and this is just an
    // example you'll have to update
    return new Dimension(200, 200);
}

现在,您可以创建 Graph 的实例并将其添加到您想要的任何容器中