2016-06-24 5 views
1

私のプログラムで何度も再利用できるカスタムJComponentを作成しようとしています。私は何をする必要があるのか​​簡単なテストを設定しましたが、私はそれを働かせることさえできません。複数のカスタムJComponents、1つしか表示されない

class MyComponent extends JComponent { 
    private String string = ""; 
    private int x; 
    private int y; 

    public MyComponent(String string, int x, int y){ 
     this.string = string; 
     this.x = x; 
     this.y = y; 
    } 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawString(string, x, y); 
    } 

} 

public class GObject { 
    public static void main(String[] args) { 
     JFrame Window = new JFrame(); 
     Window.setBounds(30, 30, 300, 300); 
     Window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     MyComponent com1 = new MyComponent("test123", 100, 100); 
     MyComponent com2 = new MyComponent("test456", 20, 20); 
     Window.add(com1); 
     Window.add(com2); 

     Window.setVisible(true); 
    } 
} 

技術的には、どこにでも配置できるJLabelです。これらの座標に "test123"と "test456"という2つの文字列が表示されます。しかし、私は最後に表示された文字列しか表示しません。

enter image description here

JFrame with only one string of text displayed.

EDIT:

私の実際のコードをアップロードしてみましょう。私は実際のコードをダンピングして物事を単純化しようとしました。

import java.awt.Graphics; 

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

public class HeatG2 { 
    public static JFrame frame = new JFrame("Test"); 

    public static void main(String[] args){ 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     Sheet sheet = new Sheet(); 
     frame.add(sheet); 
     frame.setSize(1000, 800); 
     frame.setVisible(true); 
    } 

} 

@SuppressWarnings("serial") 
class Sheet extends JPanel{ 
    public Heat test1; 
    public Heat test2; 

    public Sheet(){ 
     test1 = new Heat(); 
     test1.setPosition(10, 10); 
     test1.setHeat(1); 
     test1.setHeight(150); 
     add(test1); 

     test2 = new Heat(); 
     test2.setPosition(10, 310); 
     test2.setHeat(2); 
     test2.setHeight(150); 
     add(test2); 
    } 
} 

@SuppressWarnings("serial") 
class Heat extends JComponent{ 
    private int x; 
    private int y; 
    private int height; 
    private int heat; 
    private String driver1 = ""; 
    private String driver2 = ""; 

    public String getDriver1(){ 
     return driver1; 
    } 

    public String getDriver2(){ 
     return driver2; 
    } 

    public void setDriver1(String driver1){ 
     this.driver1 = driver1; 
     System.out.println(this.driver1); 
    } 

    public void setDriver2(String driver2){ 
     this.driver2 = driver2; 
     System.out.println(this.driver2); 
    } 

    public void setPosition(int x, int y){ 
     this.x = x; 
     this.y = y; 
    } 

    public void setHeight(int height){ 
     this.height = height; 
    } 

    public void setHeat(int heat){ 
     this.heat = heat; 
    } 

    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     g.drawString(driver1, x, y); 
     g.drawLine(x, y, x+250, y); 
     g.drawLine(x+250, y, x+250, y+height); 
     g.drawString(driver2, x, y+height); 
     g.drawLine(x, y+height, x+250, y+height); 
    } 
} 

複数の加熱は、シート(JPanelの)上の指定の場所に追加する必要があります。ここでは

は私が持っているものです。 JpanelがJWindowに追加されます。

EDIT 2:

私はコンポーネントを拡張しないことによって、この問題を修正することになりました。私は代わりにpaintableオブジェクトのテンプレートとしてクラスを使用しました。

+1

[コード慣習](http:// www。oracle.com/technetwork/java/codeconventions-135099.html)、変数名は小文字にする必要があります。また、クラスウィンドウ(これはそうではありませんが、変数名は "Window")を呼び出すことはありません。[ウィンドウクラス](https://docs.oracle.com/javase/7/docs)で問題が発生する可能性があります。 /api/java/awt/Window.html) – Frakcool

答えて

2

ような何か、私は絶対位置を使用するために必要なコンポーネントは、最終的には、スクロールペインに追加されますので、

スクロールペインおよびその関連スクロールバーがするので、スクロールが絶対ポジショニングでは動作しません。パネルの適切なサイズがスクロールペインのサイズよりも大きい場合にのみ機能します。レイアウトマネージャを使用しない場合は、希望のサイズを自分で管理する必要があります。

パネルの好ましいサイズを管理するDrag Layoutのようなものを使用する必要があります。

私が作成した技術は、どこにでも配置できるJLabelです。

技術的には、JLabelを使用してホイールを再構築しないでください。コンポーネントがどのように機能するかという概念は間違っています。コンポーネントはsizelocationです。したがって、カスタムペイントは、コンポーネントの(0、0)を基準としてテキストをペイントします。次に、setLocation(...)メソッドを使用して、親パネルにコンポーネントを配置します。

カスタムペイントを行う場合は、各コンポーネントの推奨サイズを決定する必要があります。サイズはパラメータとして指定するテキストに応じて異なるため、FontMetricsを使用する必要があります。これがJLableを使うもう一つの理由です。

+0

ありがとう、私は今理解していると思う。いくつかのことをクリアするために私の元の投稿の編集を参照してください。 @camickr – Aaron

4

レイアウトを確認する必要があります。 BorderLayout(デフォルト)の場合は、最後のレイアウトだけが異なるレイアウトを使用しようとします。 GridLayoutのかFlowLayoutの

+0

特定の座標に配置するものが必要な場合は、レイアウトマネージャをnullに設定する必要がありますか? – Aaron

+0

ウィンドウのサイズが変更されない場合、nullレイアウトに設定することができます。一般的に私たちはあなたにヌルレイアウトをありません。 – Beniton

+0

コンポーネントが最終的にスクロールペインに追加されるため、絶対配置を使用する必要があります。ユーザーがウィンドウのサイズを変更すると、スクロールするだけで済みます。ほとんどのコンテンツはすでに「オフスクリーン」になっています。 – Aaron

関連する問題