2013-05-10 80 views
1

我基本上試圖通過調用第二個組件的paint來將第一個組件的圖形傳遞給另一個組件,從而在另一個內部繪製JComponent。我想創建一個GUI編輯器,(重新發明輪子,我知道,它只是一個概念證明) 所以我有一個類擴展JPanel,我想從VectorControls中繪製組件。使用其圖形繪製控制另一個

到目前爲止,我在擴展的JPanel了這種方法:

@SuppressWarnings("serial") 
public class Sketch extends JPanel { 
    private Vector<JComponent> controls = new Vector<JComponent>(); 

    public Sketch() { 
     super(); 
     this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS)); 
    } 

    public void addControl(JComponent c) { 
     Dimension d = new Dimension(100,50); 
     c.setPreferredSize(d); 
     c.setMinimumSize(d); 
     c.setMaximumSize(d); 
     controls.add(c); 
     this.repaint(); 
     this.revalidate(); 
    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     for(int i=controls.size()-1; i>=0; i--) { 
      JComponent c = controls.get(i); 
      c.paint(g); 
     }  
    } 
} 

我建立/安裝草圖面板是這樣的:

public GUIEditor() { 
    mainFrame = new JFrame("GUI EDITOR"); 
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    Sketch mainPanel = new Sketch(); 
    mainPanel.setPreferredSize(new Dimension(640,480)); 

    GridBagLayout gbl = new GridBagLayout(); 
    GridBagConstraints gbc = new GridBagConstraints(); 

    mainFrame.setLayout(gbl); 

    JPanel toolsPanel = new JPanel(); 
    toolsPanel.setPreferredSize(new Dimension(160,480)); 
    toolsPanel.setLayout(new GridLayout(0,1));  

    for(Control c : toolBoxItems) { 
     AbstractAction action = new ToolBoxButtonAction(mainPanel, c.type); 
     JButton b = new JButton(action); 
     b.setText(c.title); 
     toolsPanel.add(b); 
    } 

    gbc.gridx = 0; 
    gbc.gridy = 0; 
    gbl.setConstraints(mainPanel, gbc); 
    mainFrame.add(mainPanel); 

    gbc.gridx = 1; 
    gbc.gridy = 0; 
    gbl.setConstraints(toolsPanel, gbc); 
    mainFrame.add(toolsPanel); 

    mainFrame.pack(); 
    mainFrame.setLocationRelativeTo(null); 
    mainFrame.setVisible(true); 
} 

裏面ToolBoxButtonAction,基本上我這樣做:

public void actionPerformed(ActionEvent e) { 
    try { 
     sketch.addControl(control.newInstance()); 
    } catch (InstantiationException e1) { 
     e1.printStackTrace(); 
    } catch (IllegalAccessException e1) { 
     e1.printStackTrace(); 
    } 
} 

但我寫這個,因爲它不工作。

有關如何實現此目的的任何想法?

+0

是'Controls'類還是'ArrayList '?如果它是一個列表,它應該被聲明爲'controls'(小寫)以方便閱讀。 – wchargin 2013-05-10 14:31:51

+0

*它不起作用*發生了什麼? – johnchen902 2013-05-10 14:33:04

+0

@ johnchen902它不工作,因爲我沒有看到任何東西繪製到我的JPanel – 2013-05-11 00:32:06

回答

4

我基本上試圖通過調用第二個組件的paint將第一個組件的Graphics傳遞給另一個組件,在另一個內部繪製一個JComponent。

組件只能在組件具有非零大小時繪製。通常,組件的大小由佈局管理器決定。

您的基本代碼看起來很合理,但除非您有代碼來確定大小並找到組件,否則您將看不到任何內容。如果你只是設置大小,那麼所有的組件將會彼此重疊。

或者問題可能是您的父面板沒有大小,所以它甚至沒有畫。默認FlowLayout使用子組件的首選大小來確定面板大小。由於您不直接向面板添加組件,因此沒有子組件,因此首選大小將爲0.當您重新發明輪子時,您需要重新創建所有內容。

沒有SSCCE,你如何使用這段代碼的背景是未知的,我們所能做的就是猜測。

編輯:

創建SSCCE當你有問題,並把它與硬編碼值的工作努力得到它的動態工作之前。例如:

import java.awt.*; 
import java.awt.event.*; 
import java.util.*; 
import javax.swing.*; 

public class Sketch extends JComponent 
{ 
    private Vector<JComponent> controls = new Vector<JComponent>(); 

    public void addControl(JComponent c) 
    { 
     c.setSize(100, 50); 
     int location = controls.size() * 50; 
     c.setLocation(location, location); 
     controls.add(c); 
     repaint(); 
    } 

    @Override 
    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 

     for(int i=controls.size()-1; i>=0; i--) 
     { 
      JComponent c = controls.get(i); 
      Point location = c.getLocation(); 
      g.translate(location.x, location.y); 
      c.paint(g); 
      g.translate(-location.x, -location.y); 
     } 
    } 

    private static void createAndShowUI() 
    { 
     Sketch sketch = new Sketch(); 
     sketch.addControl(new JButton("button")); 
     sketch.addControl(new JTextField(10)); 
     sketch.addControl(new JCheckBox("Checkbox")); 

     JFrame frame = new JFrame("Sketch"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(sketch); 
     frame.setSize(400, 400); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 
+0

我編輯以反映它是如何實施的。正如您所看到的,我將一個大小分配給「草圖」面板。我不得不說,如果我直接添加JComponent(使用繼承的「add」方法),它顯示正確,但我不希望它成爲「真正的」JComponent,我只需要它的圖像。 – 2013-05-11 00:50:15

+0

btw,我知道我必須翻譯Graphics對象才能將所有東西都放在正確的位置,現在我很高興如果我可以將所有組件堆在某個地方。 – 2013-05-11 01:04:27

+0

@マルちゃんだよ,你還沒有發佈SSCCE。請參閱我的編輯瞭解SSCCE的示例。 – camickr 2013-05-11 01:16:17

2
+0

非常好的工作!我的想法是使用UMLET(http://www.umlet.com/)樣式進行編輯,並將其與XAML樣式混合以格式化表單信息文件。 – 2013-05-11 01:00:04