我正在使用Swing with Spring创建一个财务应用程序。在我的应用程序的一部分中,我有一个JList
,其中包含应用程序中每个JLabel
的{{1}}。点击Account
后,我想在JLabel
中显示JPanel
类型AccountTab
。这都在以下控制器中执行。
JTabbedPane
每个@Component
public class AccountListController extends MouseAdapter implements MouseListener {
@Autowired
private AccountService accountService;
@Autowired
private MainFrameView mainFrameView;
@Autowired
private ApplicationContext context;
@Override
public void mouseClicked(MouseEvent e) {
if (e.getSource() instanceof JList) {
JList list = (JList) e.getSource();
JTabbedPane tabbedPane = this.mainFrameView.getTabbedPane();
SidebarItem item = (SidebarItem) list.getModel().getElementAt(list.getSelectedIndex());
Account account = accountService.findById(item.getValue());
if (tabbedPane.indexOfTab(account.getName()) == -1) {
AccountTab panel = context.getBean(AccountTab.class);
panel.addTransactions(account.getTransactions());
panel.getSplitPane().setDividerLocation(500);
tabbedPane.addTab(item.getTitle(), panel);
}
tabbedPane.setSelectedIndex(tabbedPane.indexOfTab(account.getName()));
}
}
}
点击AccountTab
更改,因此我将JLabel
设为原型bean,因此我收到了每个帐户的新实例。为了使原型范围有效,我需要使用AccountTab
。这是context.getBean(AccountTab.class)
代码:
AccountTab
您会注意到我尝试自动装配类型为@Component
@Scope("prototype")
public class AccountTab extends JPanel {
@Autowired
private AccountTransactionPane transactionPane;
private static final long serialVersionUID = 1L;
private JTable table = new JTable();
private JSplitPane splitPane;
public AccountTab() {
this.setLayout(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(this.table);
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, transactionPane);
splitPane.setEnabled(false);
this.add(splitPane, BorderLayout.CENTER);
}
public void addTransactions(List<AccountTransaction> transactions) {
this.table.setModel(new AccountTransactionTableModel(transactions));
}
//omitted rest of code
}
的bean,但是,bean没有正确自动装配,它为空。以下是AccountTransactionPane
的代码:
AccountTransactionPane
我有一个具体问题和一个一般问题。首先,@Component
public class AccountTransactionPane extends JPanel {
private static final long serialVersionUID = 1L;
JTabbedPane tabbedPane = new JTabbedPane();
private JPanel withdrawlTransactionPane = new DepositTransactionPane().build();
private JPanel depositTransactionPane = new DepositTransactionPane().build();
private JPanel transferTransactionPane = new DepositTransactionPane().build();
public AccountTransactionPane() {
this.setLayout(new BorderLayout());
tabbedPane.addTab("Withdrawl", this.withdrawlTransactionPane);
tabbedPane.addTab("Deposit", this.depositTransactionPane);
tabbedPane.addTab("Transfer", this.transferTransactionPane);
this.add(tabbedPane, BorderLayout.CENTER);
}
//rest of class omitted
}
未在AccountTransactionPane
bean中自动装配。我不知道为什么,如何在AccountTab
内自动装配AccountTransactionPane
bean?
我的第二个问题更为笼统,我正在自动装配一切。好像一切都需要成为一个豆子。我已经陷入了创建控制器(bean)的模式,注入UI(bean),然后注入另一个用作监听器的控制器(bean),在该控制器中我注入一个服务(bean)。这是正常的吗?我找不到任何有关Swing Spring应用程序的好例子来指导我。
更新:Spring Java Config
AccountTab
答案 0 :(得分:1)
注射过程就像这样
Class
实例以创建Constructor
或使用Class#newInstance()
创建bean @Autowired
目标注入bean。你的类'构造函数就像
@Autowired
private AccountTransactionPane transactionPane;
...
public AccountTab() {
this.setLayout(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(this.table);
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, transactionPane);
splitPane.setEnabled(false);
this.add(splitPane, BorderLayout.CENTER);
}
显然transactionPane
在构造函数中将是null
。 Spring还没有注射它。如果您需要对注入的bean进行一些初始化,请考虑使用@PostConstruct
带注释的方法。
我的第二个问题更为笼统,我正在自动装配一切。它 好像一切都需要成为一个豆子。我陷入了困境 模式创建一个控制器(bean),注入UI(bean),然后注入 另一个用作监听器的控制器(bean) controller我注入了一个服务(bean)。这是正常的吗?
应用程序应该有一个加载Spring ApplicationContext
的入口点。每个其他组件(及其依赖项)都应由ApplicationContext
管理。
答案 1 :(得分:1)
使用 init 方法构建面板而不是Ctor。自动装配在施工后完成。
即:
@PostConstruct
public void init() {
this.setLayout(new BorderLayout());
JScrollPane scrollPane = new JScrollPane(this.table);
splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane, transactionPane);
splitPane.setEnabled(false);
this.add(splitPane, BorderLayout.CENTER);
}
您还可以在Ctor中注入transactionPane:
@Autowired
public AccountTab(AccountTransactionPane transactionPane) {
...
}