Java - Swing - 似乎无法使增量绘画工作(通过可执行 Jar 文件运行)
Java - Swing - Can't seem to get Incremental Painting to work (Runned through Executable Jar File)
我正在尝试构建一个周期性的 table 元素程序。我有几个 类 和一个用作数据库的 JSON 文件。我使用 executable jar 文件有几个原因,其中一个最大的原因是因为 Applet 安全限制不适用于我读取像 JSON 文件这样的文件。
周期性 table 图像将是部分静态的。目前的计划是画出来,用一个二维数组和光标的位置来决定其他的动作。 (此类操作包括显示有关元素的额外信息的弹出菜单)
我的问题:我认为我拥有的东西应该可以工作,但最后只显示了一个元素块。 (而且它甚至没有被正确绘制......那一小部分可能是我稍后可以找到的一些小错误)
显示如下:(这是元素的周期性 Table...有 post 是 118 个元素)
这是我的源文件:
(主要源文件)
package PeriodicTable;
class PeriodicTable {
public static void main (String[] args) {
Table table = new Table();
}
}
我的总体json结构如下:
JsonObject 持有 JsonArray(元素)
元素包含 118 个 JsonObject(每个元素 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);
}
}
}
我在使用什么versions/programs/etc?
记事本
命令提示符
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 还是很陌生,我的实际教育程度一直到高中在线计算机科学课程结束时为止。虽然在从事这个额外的项目时,我在课程之外学到了很多东西。
明确说明我的问题...
关于为什么增量绘画不起作用的任何线索?我该如何解决这个问题?
这里发生了很多问题,但立即想到的最大的 3 个问题:
- 您正在覆盖
update(Graphics g)
方法,并在其中调用 paintComponent
。您不应该在 Swing GUI 中覆盖此方法,这是一种 AWT 类型的东西,您当然不应该像您的代码那样更改其固有行为。
- 您没有在重写中调用 super 的 paintComponent 方法。
- 最重要的是,您直接将元素组件添加到 JFrame 而不用 更改 JFrame 的默认 BorderLayout 布局管理器——您认为这会做什么?也许让它只显示最后输入的项目!
考虑创建一个使用更好布局的 JPanel,GridLayout 可能效果最好,并将您的元素组件添加到此 JPanel,然后将该 JPanel 添加到您的 GUI。
请注意,周期性 table 将有空元素的位置,对于那些,将空白 JLabel 添加到您的 GridLayout-using JPanel。
另一个问题:如果您要正确使用布局,那么您将希望每个元素在相对于该元素的坐标系中绘制其图像,而不是 table。换句话说,每个元素会将其图像和文本放置在相同的相对位置。绝对位置会有所不同,因为每个元素都会在 JPanel 上占据自己不同的绝对位置。
就像对我自己的问题的编辑一样,我正在玩另一个问题的周期性 table 数据显示,并尝试创建一个简化的周期性 table,其中没有镧系元素和锕系元素元素,并使用简单的 Swing GUI。
我创建了一个简单的 Element.java class,它只包含元素中最基本的信息:
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 + "]";
}
}
然后我创建了这个数据 table,Elements.txt
,将这个文件放在 与 class 文件相同的 目录中:
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 为 table 创建每个元素单元格,并使用 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());
}
}
这显示为:
我正在尝试构建一个周期性的 table 元素程序。我有几个 类 和一个用作数据库的 JSON 文件。我使用 executable jar 文件有几个原因,其中一个最大的原因是因为 Applet 安全限制不适用于我读取像 JSON 文件这样的文件。
周期性 table 图像将是部分静态的。目前的计划是画出来,用一个二维数组和光标的位置来决定其他的动作。 (此类操作包括显示有关元素的额外信息的弹出菜单)
我的问题:我认为我拥有的东西应该可以工作,但最后只显示了一个元素块。 (而且它甚至没有被正确绘制......那一小部分可能是我稍后可以找到的一些小错误)
显示如下:(这是元素的周期性 Table...有 post 是 118 个元素)
这是我的源文件: (主要源文件)
package PeriodicTable;
class PeriodicTable {
public static void main (String[] args) {
Table table = new Table();
}
}
我的总体json结构如下:
JsonObject 持有 JsonArray(元素)
元素包含 118 个 JsonObject(每个元素 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);
}
}
}
我在使用什么versions/programs/etc?
记事本
命令提示符
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 还是很陌生,我的实际教育程度一直到高中在线计算机科学课程结束时为止。虽然在从事这个额外的项目时,我在课程之外学到了很多东西。
明确说明我的问题...
关于为什么增量绘画不起作用的任何线索?我该如何解决这个问题?
这里发生了很多问题,但立即想到的最大的 3 个问题:
- 您正在覆盖
update(Graphics g)
方法,并在其中调用paintComponent
。您不应该在 Swing GUI 中覆盖此方法,这是一种 AWT 类型的东西,您当然不应该像您的代码那样更改其固有行为。 - 您没有在重写中调用 super 的 paintComponent 方法。
- 最重要的是,您直接将元素组件添加到 JFrame 而不用 更改 JFrame 的默认 BorderLayout 布局管理器——您认为这会做什么?也许让它只显示最后输入的项目!
考虑创建一个使用更好布局的 JPanel,GridLayout 可能效果最好,并将您的元素组件添加到此 JPanel,然后将该 JPanel 添加到您的 GUI。
请注意,周期性 table 将有空元素的位置,对于那些,将空白 JLabel 添加到您的 GridLayout-using JPanel。
另一个问题:如果您要正确使用布局,那么您将希望每个元素在相对于该元素的坐标系中绘制其图像,而不是 table。换句话说,每个元素会将其图像和文本放置在相同的相对位置。绝对位置会有所不同,因为每个元素都会在 JPanel 上占据自己不同的绝对位置。
就像对我自己的问题的编辑一样,我正在玩另一个问题的周期性 table 数据显示,并尝试创建一个简化的周期性 table,其中没有镧系元素和锕系元素元素,并使用简单的 Swing GUI。
我创建了一个简单的 Element.java class,它只包含元素中最基本的信息:
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 + "]";
}
}
然后我创建了这个数据 table,Elements.txt
,将这个文件放在 与 class 文件相同的 目录中:
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 为 table 创建每个元素单元格,并使用 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());
}
}
这显示为: