簡體   English   中英

Java-Swing-似乎無法使增量繪畫正常工作(通過可執行的Jar文件運行)

[英]Java - Swing - Can't seem to get Incremental Painting to work (Runned through Executable Jar File)

我正在嘗試構建元素程序的周期表。 我有幾個類,還有一個充當數據庫的JSON文件。 我使用可執行jar文件的原因有兩個,最大的原因之一是因為Applet的安全限制不適用於讀取JSON文件之類的文件。

元素周期表圖像將部分為靜態。 當前的計划是繪制出來,並使用2d數組和光標的位置來確定其他動作。 (此類操作包括一個彈出菜單,顯示有關該元素的更多信息)

我的問題:我所擁有的東西應該可以正常工作,但是最后只顯示了其中一個元素塊。 (而且甚至沒有正確繪制。...這可能是我稍后可以找到的一些小錯誤)

這是顯示的內容:(這是元素周期表...此后有118個元素) 在此處輸入圖片說明

這是我的源文件:(主源文件)

package PeriodicTable;

class PeriodicTable {
public static void main (String[] args) {
    Table table = new Table();
}
}

我的整體json結構如下:

JsonObject持有JsonArray(元素)

Elements擁有118個JsonObjects(每個元素1個對象)

JsonObjects保存其相應元素的信息

(截至目前,基本上所有未顯示在屏幕上的內容)

package PeriodicTable;

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

import javax.json.JsonArray;
import javax.json.JsonObject;

import java.awt.Toolkit;
import java.awt.Dimension;

import java.io.IOException;

class Table {
private JFrame frmMain;
private Element[][] aryElements;
Dimension dmsScreenSize;
int intScreenHeight, intScreenWidth;
DataBaseReader dbReader;
private int intElementsColumns = 18, intElementsRows = 9;//18 columns in the periodic table, 7 rows + the 2 F block rows, 6 and 7. Totals 9 rows

public Table(){
    dmsScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
    intScreenWidth = (int)dmsScreenSize.getWidth();
    intScreenHeight = (int)dmsScreenSize.getHeight();
    frmMain = new JFrame("Periodic Table of the Elements");
    frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frmMain.setMinimumSize(dmsScreenSize);
    dbReader = new DataBaseReader();
    layout("Periodic Table");
    frmMain.setVisible(true);
}
void layout(String strLayout){ //Creates the specified table, at the time there is only one.
    switch(strLayout){
        case "Periodic Table":
            periodicTable();
            break;
    }
}
private void periodicTable() {
    aryElements = new Element[intElementsRows][intElementsColumns]; //creates a two-dimensional array of the class Element, hold 9 by 18 blocks
    try{
        JsonArray jAryElements = dbReader.readDataBase(); //obtains the Element array from Elements.JSON
        Element clsElement; //Define an element instance, but not create
        for(int index = 0; index < jAryElements.size(); index++){   //go through the Element array (called jAryElements), for every json object in this array...
            clsElement = new Element(jAryElements.getJsonObject(index));//create an instance of class Element with the current selected JsonObject
            frmMain.add(clsElement);                /*add that instance to the JFrame frmMain (Element extends JPanel)
                                        *(For below) Store that instance in the 2d array
                                        *storage location is dependant on the element's row and column in the periodic table*/
            aryElements[Integer.parseInt(element.getString("row"))-1][Integer.parseInt(element.getString("columnNumber"))-1] = clsElement;
        }
    }catch(IOException ioe){
        ioe.printStackTrace();
    }

}
}

(當前正在處理所有圖形)

package PeriodicTable;

import javax.json.JsonObject;

import javax.swing.JPanel;

import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;

class Element extends JPanel {
JsonObject element;
int intX, intY, intWidth, intHeight;
Font aFont, bFont, cFont;
Element(JsonObject elementForeign){
    element = elementForeign; //Store the json object from the database here
    intWidth = 50;  //width of an element
    intHeight = 71; //height of an element
    intX = 10+(intWidth*(Integer.parseInt(element.getString("columnNumber"))));
    /*<10+> add some space to the left of the entire grid of elements
    *<intWidth*(<some code>(<some code>("columnNumber")> 
    *   position would be equal to the element width multiplied by it's column. */
    intY = 50+(intHeight*(Integer.parseInt(element.getString("row")))); //Same as intX, but vertically
    aFont = new Font("TimesRoman", Font.BOLD, 10);//some fonts for text inside each element
    bFont = new Font("TimesRoman", Font.PLAIN, 9);
    cFont = new Font("TimesRoman", Font.BOLD, 17);
}
public void update(Graphics gr){ //Post to stop the program from clearing the screen
    paintComponent(gr);
}
public void paintComponent(Graphics gr){/*painting method. I've read someone describing the activation
                    *of this method to occur "magically" when ever something happens to the container
                    *such as resizing the main window.*/
    gr.setColor(getColor(""));              //The specifics for every piece of information to be drawn inside a element block
    gr.drawRect(intX, intY, intWidth, intHeight);
    gr.setColor(getColor(element.getString("group")));
    gr.fillRect(intX+1, intY+1, intWidth-2, intHeight-2);
    gr.setColor(getColor(""));
    gr.setFont(aFont);
    gr.drawString(element.getString("atomicNumber"), intX+4, intY+10);
    gr.drawString(element.getString("molarMass"), intX+4, intY+29);
    gr.setFont(bFont);
    gr.drawString(element.getString("electronegativity"), intX+4, intY+20);
    gr.drawString(element.getString("ionCharge1"), intX+4, intY+29);
    gr.drawString(element.getString("ionCharge2"), intX+4, intY+38);
    gr.drawString(element.getString("name"), intX+(intWidth/2)-((gr.getFontMetrics().stringWidth(element.getString("name")))/2), intY+56);
    gr.setColor(getColor(element.getString("naturalState")));
    gr.setFont(cFont);
    gr.drawString(element.getString("symbol"), intX+((intWidth/2)-((gr.getFontMetrics().stringWidth(element.getString("symbol")))/2)), intY+45);
    gr.setColor(getColor(element.getString("synthetic")));
    gr.drawRect(intX+(intWidth-(2*(intWidth/5)))-1, intY+1, intWidth/5, intWidth/5);
    gr.fillRect(intX+(intWidth-(2*(intWidth/5)))-1, intY+2, intWidth/5, intWidth/5);
    gr.setColor(getColor(element.getString("diatomic")));
    gr.drawRect(intX+(intWidth-(intWidth/5))-1, intY+1, intWidth/5, intWidth/5);
    gr.fillRect(intX+(intWidth-(intWidth/5))-1, intY+2, intWidth/5, intWidth/5);
}
private Color getColor(String strType){ //Returns a color depending on the situation (the string that is passed in)
    switch(strType){
        case "Hydrogen":
            return new Color(255,229,204);
        case "Alkali Metal":
            return new Color(255,102,102);
        case "Alkali Earth Metal":
            return new Color(255,204,204);
        case "Transition Metal":
            return new Color(153,255,153);
        case "Inner-Transition Metal":
            return new Color(0,255,0);
        case "Metalloid":
            return new Color(255,0,255);
        case "Post-Transition Metal":
            return new Color(255, 153,51);
        case "Halogen":
            return new Color(255,128,0);
        case "Noble Gas":
            return new Color(204,229,255);
        case "Unknown-Post-Transition Metal":
        case "Unknown-Halogen":
        case "Unknown-Noble Gas":
        case "false":
            return new Color(255,255,255);
        case "true":
            return new Color(255,255,0);
        case "Gas":
            return new Color(255,0,0);
        case "Liquid":
            return new Color(0,0,255);
        case "Solid":
        default:
            return new Color(0,0,0);
    }
}
}

我正在使用什么版本/程序/等?

記事本

命令提示符

Java 8

javax.json-1.0.jar

該程序將javac,jar和java -jar都罰款,數據庫讀取正常,我可以使用該信息。 因此,我將不提供有關這些內容的其他信息(除非有人提出要求)。

在此之前,我曾嘗試使用布局等,但與此同時,我卻遇到了很多荒謬的事情……最終,我想到了使用2d數組來保存信息。

我搜索了許多站點,包括:

paintComponent如何工作?

http://www.oracle.com/technetwork/java/painting-140037.html

http://www.slideshare.net/martyhall/java-7-programming-tutorial-multithreaded-graphics-and-animation

Swing中的增量圖形

Java在調用paint方法時清除屏幕-如何避免這種情況?

還有很多。 有些事情我不了解,但我確實學到了很多。

請注意,我對Java還是很陌生,我的實際教育一直到一門高中在線計算機科學課程的結尾。 盡管在從事這個額外的項目時,我在課程之外學到了很多東西。

為了清楚地說出我的問題...

關於為什么增量繪畫不起作用的任何線索? 我該如何解決?

這里發生了很多問題,但立即想到了最大的3個問題:

  1. 您將覆蓋update(Graphics g)方法,並在其中調用paintComponent 您不應該在Swing GUI中重寫此方法,這是AWT的事情,並且您當然不應該像代碼那樣更改其固有行為。
  2. 您沒有在覆蓋范圍內調用上級的paintComponent方法。
  3. 最重要的是,您將元素組件直接添加到JFrame中, 而無需更改JFrame的默認BorderLayout布局管理器-您認為這會做什么? 也許這樣做,以便僅顯示最后輸入的項目!

考慮創建一個使用更好布局的JPanel,GridLayout可能會最好地工作,然后將元素組件添加到此JPanel,然后將該JPanel添加到您的GUI。

請注意,元素周期表將具有用於空白元素的斑點,對於這些元素,請使用JPanel將空白JLabel添加到GridLayout中。

另一個問題:如果要正確使用布局,則將希望每個元素在相對於元素而不是表格的坐標系中繪制其圖像。 換句話說,每個元素將其圖像和文本放置在相同的相對位置。 絕對位置將有所不同,因為每個元素在JPanel上將占據其自己不同的絕對位置。



就像對我自己的問題的編輯一樣,我正在處理元素周期表中另一個問題的顯示,並試圖創建一個簡化的元素周期表,其中不包含鑭系元素和act系元素,並使用簡單的Swing GUI。

我創建了一個簡單的Element.java類,該類僅包含元素中的最基本信息:

public class Element {
    private int atomicNumber;
    private String name;
    private String symbol;
    private int group;
    private int period;

    public Element(int atomicNumber, String name, String symbol, int group, int period) {
        this.atomicNumber = atomicNumber;
        this.name = name;
        this.symbol = symbol;
        this.group = group;
        this.period = period;
    }

    public int getAtomicNumber() {
        return atomicNumber;
    }

    public String getName() {
        return name;
    }

    public String getSymbol() {
        return symbol;
    }

    public int getGroup() {
        return group;
    }

    public int getPeriod() {
        return period;
    }

    @Override
    public String toString() {
        return "Element [atomicNumber=" + atomicNumber + ", name=" + name + ", symbol=" + symbol
                + ", group=" + group + ", period=" + period + "]";
    }

}

然后,我創建了此數據表Elements.txt ,將該文件與類文件放在同一目錄中:

1, Hydrogen, H, 1, 1
2, Helium, He, 18, 1
3, Lithium, Li, 1, 2
4, Beryllium, Be, 2, 2
5, Boron, B, 13, 2
6, Carbon, C, 14, 2
7, Nitrogen, N, 15, 2
8, Oxygen, O, 16, 2
9, Fluorine, F, 17, 2
10, Neon, Ne, 18, 2
11, Sodium, Na, 1, 3
12, Magnesium, Mg, 2, 3
13, Aluminium, Al, 13, 3
14, Silicon, Si, 14, 3
15, Phosphorus, P, 15, 3
16, Sulfur, S, 16, 3
17, Chlorine, Cl, 17, 3
18, Argon, Ar, 18, 3
19, Potassium, K, 1, 4
20, Calcium, Ca, 2, 4
21, Scandium, Sc, 3, 4
22, Titanium, Ti, 4, 4
23, Vanadium, V, 5, 4
24, Chromium, Cr, 6, 4
25, Manganese, Mn, 7, 4
26, Iron, Fe, 8, 4
27, Cobalt, Co, 9, 4
28, Nickel, Ni, 10, 4
29, Copper, Cu, 11, 4
30, Zinc, Zn, 12, 4
31, Gallium, Ga, 13, 4
32, Germanium, Ge, 14, 4
33, Arsenic, As, 15, 4
34, Selenium, Se, 16, 4
35, Bromine, Br, 17, 4
36, Krypton, Kr, 18, 4
37, Rubidium, Rb, 1, 5
38, Strontium, Sr, 2, 5
39, Yttrium, Y, 3, 5
40, Zirconium, Zr, 4, 5
41, Niobium, Nb, 5, 5
42, Molybdenum, Mo, 6, 5
43, Technetium, Tc, 7, 5
44, Ruthenium, Ru, 8, 5
45, Rhodium, Rh, 9, 5
46, Palladium, Pd, 10, 5
47, Silver, Ag, 11, 5
48, Cadmium, Cd, 12, 5
49, Indium, In, 13, 5
50, Tin, Sn, 14, 5
51, Antimony, Sb, 15, 5
52, Tellurium, Te, 16, 5
53, Iodine, I, 17, 5
54, Xenon, Xe, 18, 5
55, Caesium, Cs, 1, 6
56, Barium, Ba, 2, 6
57, Lanthanum, La, 3, 6
72, Hafnium, Hf, 4, 6
73, Tantalum, Ta, 5, 6
74, Tungsten, W, 6, 6
75, Rhenium, Re, 7, 6
76, Osmium, Os, 8, 6
77, Iridium, Ir, 9, 6
78, Platinum, Pt, 10, 6
79, Gold, Au, 11, 6
80, Mercury, Hg, 12, 6
81, Thallium, Tl, 13, 6
82, Lead, Pb, 14, 6
83, Bismuth, Bi, 15, 6
84, Polonium, Po, 16, 6
85, Astatine, At, 17, 6
86, Radon, Rn, 18, 6
87, Francium, Fr, 1, 7
88, Radium, Ra, 2, 7
89, Actinium, Ac, 3, 7
104, Rutherfordium, Rf, 4, 7
105, Dubnium, Db, 5, 7
106, Seaborgium, Sg, 6, 7
107, Bohrium, Bh, 7, 7
108, Hassium, Hs, 8, 7
109, Meitnerium, Mt, 9, 7
110, Darmstadtium, Ds, 10, 7
111, Roentgenium, Rg, 11, 7
112, Copernicium, Cn, 12, 7
113, Nihonium, Nh, 13, 7
114, Flerovium, Fl, 14, 7
115, Moscovium, Mc, 15, 7
116, Livermorium, Lv, 16, 7
117, Tennessine, Ts, 17, 7
118, Oganesson, Og, 18, 7

然后,GUI將使用BoxLayout創建表的每個元素單元格,並使用GridLayout來保存和顯示所有元素單元格:

import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.swing.*;

@SuppressWarnings("serial")
public class ElementsGui extends JPanel {

    private static final int MAX_GROUPS = 7;
    private static final int MAX_PERIODS = 18;

    public ElementsGui(List<Element> elements) {
        setLayout(new GridLayout(MAX_GROUPS, MAX_PERIODS));
        int prevGroup = 1;
        for (Element element : elements) {
            ElementPanel elementPanel = new ElementPanel(element);
            for (int i = prevGroup; i < element.getGroup() - 1; i++) {
                add(new JLabel());
            }
            add(elementPanel);
            prevGroup = element.getGroup();
        }
    }

    // a utility method for downloading the elements from the text file
    public static List<Element> extractElements(InputStream sourceStream) {
        List<Element> elements = new ArrayList<>();
        Scanner scan = new Scanner(sourceStream);
        while (scan.hasNextLine()) {
            String line = scan.nextLine();
            String[] tokens = line.split(", ");

            int atomicNumber = Integer.parseInt(tokens[0]);
            String name = tokens[1];
            String symbol = tokens[2];
            int group = Integer.parseInt(tokens[3]);
            int period = Integer.parseInt(tokens[4]);
            elements.add(new Element(atomicNumber, name, symbol, group, period));
        }
        scan.close();

        return elements;
    }

    private class ElementPanel extends JPanel {
        Element element;

        public ElementPanel(Element element) {
            this.element = element;
            JLabel nameLabel = new JLabel(element.getName(), SwingConstants.CENTER);
            JLabel symbolLabel = new JLabel(element.getSymbol(), SwingConstants.CENTER);
            JLabel atomNumbLabel = new JLabel("" + element.getAtomicNumber(), SwingConstants.CENTER);

            symbolLabel.setFont(symbolLabel.getFont().deriveFont(Font.BOLD, 32f));

            JPanel namePanel = new JPanel();
            JPanel symbolPanel = new JPanel();
            JPanel atomNumbPanel = new JPanel();

            namePanel.add(nameLabel);
            symbolPanel.add(symbolLabel);
            atomNumbPanel.add(atomNumbLabel);

            setBorder(BorderFactory.createLineBorder(Color.BLACK));
            setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
            add(namePanel);
            add(symbolPanel);
            add(atomNumbPanel);
        }

        public Element getElement() {
            return element;
        }

    }

    private static void createAndShowGui() {
        String path = "Elements.txt";
        InputStream sourceStream = ElementUtilities.class.getResourceAsStream(path);
        if (sourceStream == null) {
            String message = "\"" + path + "\"" + " not found. Program will abort";
            String title = "Path Error";
            JOptionPane.showMessageDialog(null, message, title, JOptionPane.ERROR_MESSAGE);
            System.exit(-1);
        }
        List<Element> elements = extractElements(sourceStream);

        ElementsGui mainPanel = new ElementsGui(elements);

        JFrame frame = new JFrame("Elements Gui");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

顯示為:

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM