2016-05-18 14 views
1

私は要素プログラムの周期表を作成しようとしています。私はいくつかのクラスとデータベースとしてのJSONファイルを持っています。いくつかの理由で実行可能なjarファイルを使用していますが、アプレットのセキュリティ制限がJSONファイルなどのファイルを読み込むために適用されないため、最大の原因の1つです。Java - スイング - インクリメンタルペイントが動作するように見えない(実行可能なJARファイルを介して実行)

周期表の画像は部分的に静的になります。現在の計画はそれを描画し、2次元配列とカーソルの位置を使用して他のアクションを決定することです。 (このようなアクションには、要素に関する追加情報を表示するポップアップメニューが含まれています)

問題:私の考えでは、動作するはずですが、要素ブロックの1つだけが最後に表示されているはずです。 (それは訂正されても描かれていません...その小さな部分は、おそらく私が後で見つけることができるいくつかのマイナーなバグでしょう)

ここには何が表示されます: 118個の要素)ここでenter image description here

は私のソースファイルであることを投稿されています(

JsonObjectはJsonArrayを保持しているのElem: (メインソースファイル)

package PeriodicTable; 

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

私の全体的なJSONの構造は以下の通りですエント)

要素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

細かい-jarプログラム意志のjavac、jarファイルおよびJava、データベースが細かい読み込み、I情報を使用することができます。そのため、私はそれらについての追加情報は含まない(誰かが尋ねない限り)。

これまではレイアウトなどを使ってみましたが、面倒なことがありました...最終的には、2次元アレイを使用して情報を保持することを考えていました。

私には、多くのサイトを検索した:

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の方が新しいので、私の実際の教育は高校のオンラインコンピュータサイエンスコースの終わりまでです。この余分なプロジェクトに取り組んでいるうちに、私はコースの外で多くのことを学びました。明らかに私の質問に状態に

...インクリメンタル絵が動作していない理由として

任意の手掛かり?どうすればこの問題を解決できますか?

答えて

2

すぐに頭に浮かぶここで起こった問題の多くが、最大3:

  1. あなたはupdate(Graphics g)メソッドをオーバーライドし、その中にpaintComponentを呼んでいます。 Swing GUIでこのメソッドをオーバーライドする必要はありません。これはAWTのようなものです。あなたのコードと同じように本来の動作を変更すべきではありません。
  2. オーバーライド内でsuperのpaintComponentメソッドを呼び出すことはありません。
  3. 最も重要なことは、がJFrameのデフォルトのBorderLayoutレイアウトマネージャを変更することなく、JFrame に直接要素コンポーネントを追加していることです。これはどうなると思いますか?おそらく、最後に入力した項目だけが表示されるようにしてください!

より良いレイアウトを使用するJPanelを作成すると、GridLayoutが最もうまく機能し、要素コンポーネントをこのJPanelに追加して、そのJPanelをGUIに追加することを検討してください。

周期表には空の要素のスポットがあり、そのために空白のJLabelをJPanelを使用してGridLayoutに追加することに注意してください。

もう1つの問題:レイアウトを適切に使用する場合は、各要素が、テーブルではなく要素に関連する座標系のイメージを描画する必要があります。言い換えれば、各要素は、画像とテキストを同じ相対位置に配置します。各要素がJPanel上の異なる絶対位置を占有するため、絶対位置は異なります。ただ、私自身の質問に編集として



、私は、周期表のデータを別の質問から表示を再生し、かつ単純化された周期表を作成しようとしました、ランタノイド及びアクチノイド元素のないものだった、とシンプルなSwing GUIを使用します。

私は単純な要素を作成しました。唯一の要素の中で最も基本的な情報を保持している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

+0

私はあなたが提案してきたものに、さらに見てみましょう。それは時間がかかるだろうが。 – Tyler

+0

@タイラー:いいです。また、周期表には空の要素のスポットがあり、その場合、JPanelを使用してGridLayoutに空白のJLabelを追加します。 –

+0

@タイラー:問題の分析が間違っていることにも注意してください。主に「paintComponent」の問題ではありません。あなたのpaintComponentやその他のペイントメソッドには問題がありますが、主な問題は単純にレイアウトの問題でした。 –

関連する問題