2013-12-02 2 views
1

, если вы посмотрите на мой код ниже, то, что я пытаюсь сделать, это изменить мой метод addExpense() для создания новой ExpensePanel и добавить ее к одной из моих панелей (панель 3) и вектор и обновить пользовательский интерфейс на панели 3 и обновить статистику.Невозможно обновить интерфейс на панели

Однако после бесчисленных изменений я не могу заставить его работать. Может ли кто-нибудь дать представление?

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridBagLayout; 
import java.awt.GridLayout; 
import java.awt.Panel; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Vector; 

import javax.swing.Box; 
import javax.swing.BoxLayout; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextField; 
import javax.swing.UIManager; 

class Expenses extends JFrame implements ActionListener{ 

    ExpensesPanel widget; 
    public String n; 
    public String d; 
    public int c; 
    public int e; 

    public Expenses(){ 

     // Set Dimension, size, and close operations 
     setSize(400,400); 
     setTitle("Expenses"); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setResizable(true); 
     setLocationRelativeTo(null); 

     // Set the look and feel of the application to that if the OS 
     try{ 
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
     } catch(Exception e){ 
      System.out.print(e); 
     } 

     // Add Panel 1, or our main panel 
     JPanel p1 = new JPanel(); 
     getContentPane().add(p1); 
     p1.setLayout(new BoxLayout(p1, BoxLayout.Y_AXIS)); 

     // Add our second panel, panel 2 with a grid layout 
     JPanel p2 = new JPanel(); 
     p2.setLayout(new GridLayout(4,2)); 
     p1.add(p2); 

     // Add our labels 
     JLabel label1 = new JLabel("Name: ", JLabel.LEFT); 
     JTextField name = new JTextField(JTextField.EAST); 
     n = name.getText(); 
     JLabel label2 = new JLabel("Date: ", JLabel.LEFT); 
     JTextField date = new JTextField(JTextField.EAST); 
     d = date.getText(); 
     JLabel label3 = new JLabel("Cost: ", JLabel.LEFT); 
     JTextField cost = new JTextField(JTextField.EAST); 
     p2.add(label1); 
     p2.add(name); 
     p2.add(label2); 
     p2.add(date); 
     p2.add(label3); 
     p2.add(cost); 
     // Add our buttons 
     JButton b1 = new JButton("Add"); 
     p2.add(b1); 
     JButton b2 = new JButton("Clear"); 
     p2.add(b2); 
     // Set the preferred size of our windows 
     p2.setMaximumSize(new Dimension(Integer.MAX_VALUE, p2.getPreferredSize().height)); 

     // Panel 3, this will hold the expenses panel 
     final JPanel p3 = new JPanel(); 
     p3.setLayout(new BoxLayout(p3, BoxLayout.Y_AXIS)); 
     JScrollPane scroll = new JScrollPane(p3); 
     p1.add(scroll); 

     // Panel 4, with a 2x2 Grid 
     JPanel p4 = new JPanel(); 
     p4.setLayout(new GridLayout(2,2)); 
     p1.add(p4); 
     // Add labels, and ensure they are not editable 
     JLabel p4l1 = new JLabel("Total", JLabel.LEFT); 
     JTextField p4t1 = new JTextField(JTextField.EAST); 
     p4t1.setEditable(false); 
     JLabel p4l2 = new JLabel("Average", JLabel.LEFT); 
     JTextField p4t2 = new JTextField(JTextField.EAST); 
     p4t2.setEditable(false); 
     p4.add(p4l1); 
     p4.add(p4t1); 
     p4.add(p4l2); 
     p4.add(p4t2); 
     // Set the preferred size to fit the rest of the window 
     p4.setMaximumSize(new Dimension(Integer.MAX_VALUE, p2.getPreferredSize().height)); 

     // Action listeners for both buttons 
     // Action listner for button 1 
     b1.addActionListener(new ActionListener(){ 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("Button 1 Clicked"); 
       addExpense(p3); 
      } 

     }); 

     // Action Listener for button 2 
     b2.addActionListener(new ActionListener(){ 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("Button 2 Clicked"); 
      } 

     }); 

    } 

    public void addExpense(JPanel p3){ 
     Vector expenseHolder = new Vector(); 
     ExpensesPanel e = new ExpensesPanel(n, d, 2, 1); 
     p3.add(e); 
     expenseHolder.add(p3); 
     p3.revalidate(); 
    } 

    @Override 
    public void actionPerformed(ActionEvent arg0) { 
     // TODO Auto-generated method stub 

    } 

    public static void main(String[] args){ 
     // Main method 
     Expenses e = new Expenses(); 
     // Set the application to be visible 
     e.setVisible(true); 
    } 
} 

class ExpensesPanel extends JPanel{ 

    public String n; 
    public String d; 
    public int c; 
    public int e; 

    public ExpensesPanel(String name, String date, int cost, int expense){ 
     n = name; d = date; c = cost; e = expense; 

     // Create new Panel and set it on horizontal axis 
     JPanel exp = new JPanel(); 
     exp.setLayout(new BoxLayout(exp, BoxLayout.X_AXIS)); 
     Box horizontalBox; 

     // Labels 
     JLabel newName = new JLabel("Name: ", JLabel.CENTER); 
     JLabel newDate = new JLabel("Date", JLabel.CENTER); 
     JLabel newCost = new JLabel("Cost: ", JLabel.CENTER); 
     JLabel newExp = new JLabel("Expense: ", JLabel.CENTER); 
     exp.add(newName, Box.createHorizontalGlue()); 
     exp.add(newDate, Box.createHorizontalGlue()); 
     exp.add(newCost, Box.createHorizontalGlue()); 
     exp.add(newExp, Box.createHorizontalGlue()); 

    } 

    // Override default paint component 
    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setBackground(Color.BLUE); 
    } 
} 
+0

Что происходит не так? –

+0

Панель не обновляется. Другими словами, ничего не происходит. – Zy0n

ответ

1

Ваша проблема в том, что ваш классе ExpensePanel имеет два JPanels, один добавляемые компоненты называются, ехр, а с другой стороны, this или JPanel, который является объектом класса, вы не добавляете компонентов , Ну, вы добавляете второй JPanel в свой графический интерфейс, поэтому ничего не отображается. Заметим также, что exp объявляется в конструкторе, и поэтому его область действия ограничена только конструктором.

Одно из возможных решений: избавиться от exp и добавить все, чтобы this. Обратите внимание, что вы можете использовать форму выражения this., такую ​​как this.add(someComponent), которая явно показывает ваше намерение, но это необязательно и добавляет лишние слова с небольшой пользой в этой ситуации, поэтому я вообще избегаю этого.

т.е. изменить свой конструктор:

public ExpensesPanel(String name, String date, int cost, int expense) { 
    n = name; 
    d = date; 
    c = cost; 
    e = expense; 

    // Create new Panel and set it on horizontal axis 
    // JPanel exp = new JPanel(); 
    setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); 
    Box horizontalBox; 

    // Labels 
    JLabel newName = new JLabel("Name: ", JLabel.CENTER); 
    JLabel newDate = new JLabel("Date", JLabel.CENTER); 
    JLabel newCost = new JLabel("Cost: ", JLabel.CENTER); 
    JLabel newExp = new JLabel("Expense: ", JLabel.CENTER); 
    add(newName, Box.createHorizontalGlue()); 
    add(newDate, Box.createHorizontalGlue()); 
    add(newCost, Box.createHorizontalGlue()); 
    add(newExp, Box.createHorizontalGlue()); 
} 

Другим возможным решением является сохранение ехр JPanel, но продвигать его, чтобы быть поля экземпляра с помощью метода газопоглощающего, а затем не ExpensesPanel расширить JPanel. Любой из них будет работать, и для него есть некоторые преимущества, которые должны обсуждаться позднее (в отношении преимуществ использования композиции над наследованием).


Как и в сторону, это не будет делать ничего:

public void paintComponent(Graphics g){ 
    super.paintComponent(g); 
    Graphics2D g2d = (Graphics2D) g; 
    g2d.setBackground(Color.BLUE); 
} 

, так как вы никогда не рисовать или ясный (clearRect(...) фактически) с g2d после изменения цвета состояния.

лучше и намного проще, чтобы позвонить в конструкторе:

setBackground(Color.blue); 

Проблема в следующем, это неправильно:

add(newCost, Box.createHorizontalGlue()); 

Это не так, как вы добавить клей. Пожалуйста, ознакомьтесь с учебниками и API по этому вопросу - вы делаете ужасную работу, которая никогда не работает.

+0

Спасибо за ответ! Да, я понимаю, что я много работаю. Но это самое интересное, что я нахожу в нем, видя, что работает, а что нет, и затем учиться на этом. – Zy0n

1

Как @Hovercraft Full Of Угри ответ, вы должны также вносить изменения в компоненты графического интерфейса через что-то вроде ...

EventQueue.invokeLater(new Runnable(){ 
    public void run() 
    { 
    //make gui change here 
    } 
}); 

Это обновляет его с диспетчерским потока событий (EDT).

Смежные вопросы