Java - Swing - 似乎无法使增量绘画工作(通过可执行Jar文件运行)

时间:2016-05-18 23:12:12

标签: java json swing command-prompt notepad

我正在尝试构建元素程序的周期表。我有几个类,一个JSON文件充当数据库。我使用可执行jar文件有几个原因,其中一个原因是Applet安全限制不适用于读取JSON文件等文件。

周期表图像将部分静态。当前的计划是将其绘制出来,并使用二维数组和光标的位置来确定其他操作。 (此类操作包括一个弹出菜单,显示有关元素的额外信息)

我的问题:我所拥有的,我认为应该有效,但最后只显示了一个元素块。 (而且它甚至没有被正确地绘制......那个小部分可能是我后来可以找到的一些小错误)

以下是显示的内容:(这是元素的周期表...有118个元素的帖子) enter image description here

这是我的源文件: (主要档案资料)

package PeriodicTable;

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

我的整体json结构如下:

JsonObject拥有JsonArray(Elements)

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很好,数据库读得很好,我可以使用这些信息。出于这个原因,我不会包含有关这些的其他信息(除非有人问)。

在此之前,我已经尝试过使用布局等等,但是我遇到了一个荒谬的麻烦......最终我想到了使用二维数组来保存信息。

我搜索了很多网站,包括:

How does paintComponent work?

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

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

Incremental graphics in Swing

Java clears screen when calling paint method - how to avoid that?

还有更多。我不明白的一些事情,但我确实学到了相当多的东西。

请注意,我对java仍然很陌生,我的实际教育一直到高中在线计算机科学课程结束。虽然在开展这个额外的项目时,我已经学到了很多东西。

清楚说明我的问题......

有关为什么增量绘画不起作用的任何线索?我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

这里出现了很多问题,但最让人想到的就是:

  1. 您已覆盖update(Graphics g)方法,并在其中调用paintComponent。你不应该在Swing GUI中覆盖这种方法,这是一种AWT类型的东西,你当然不应该像你的代码那样改变它的先天行为。
  2. 你没有在你的覆盖中调用super的paintComponent方法。
  3. 最重要的是,您将元素组件直接添加到JFrame 而不更改JFrame的默认BorderLayout布局管理器 - 您认为这会做什么?也许这样做只显示输入的最后一项!
  4. 考虑创建一个使用更好布局的JPanel,GridLayout可能效果最好,并将元素组件添加到此JPanel,然后将该JPanel添加到GUI。

    请注意,元数据周期表中将包含空元素的位置,对于这些元素,请使用JPanel将空白JLabel添加到GridLayout。

    另一个问题:如果您要正确使用布局,那么您将希望每个元素在坐标系中相对于元素而不是表格绘制它的图像。换句话说,每个元素将其图像和文本放在相同的相对位置。绝对位置会有所不同,因为每个元素都会占据JPanel上不同的绝对位置。

    就像我自己的问题的编辑一样,我正在使用周期表数据来显示另一个问题,并试图创建一个简化的周期表,一个没有镧系元素和act系元素,并使用一个简单的Swing GUI。 / p>

    我创建了一个简单的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());
        }
    }
    

    显示为:

    enter image description here