然后在'main'类中,我将'panel'添加到JFrame中。
我的问题是,我正在尝试实现一个actionListener到一个添加在'Panel'类内部的按钮。actionListener函数将添加更多按钮并使用G.DrawString的按钮。现在,我要将ActionListener放置在哪里,以便这样做呢?如何将g.drawString用于特定的面板,而g.drawString行位于另一个类(即ActionListener类)内部?我需要在ActionPerformed中使用paintComponent的图形g。
谢谢你!
编辑-代码示例:
public class Main{
private JFrame jf;
private JTextField jtf1;
private JTextField jtf2;
private Panel p;
private JComboBox jcb1;
private JComboBox jcb2;
private JButton button;
private Object options[];
//ActionListener Variables
private int string1 = 150;
private int string2 = 150;
private int yJtf1 = 150;
private int yJtf2 = 160;
private int cb1 = 140;
private int cb2 = 165;
private int count = 0;
public Main(){
jf= new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(700, 700);
p = new Panel();
jtf1 = new JTextField("", 20);
jtf2= new JTextField("", 20);
Object options[] = {""};
jcb1 = new JComboBox(tools);
jcb2 = new JComboBox(tools);
button = new JButton("+");
jf.add(p);
jf.setVisible(true);`
}
public class Panel extends JPanel{
public Panel(){
this.setLayout(null);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
/*button.addActionListener(new ActionListener(){ //Would this work or should the ActionListener be a class as shown below?
public void actionPerformed(ActionEvent e){
if(count < 3){ //Won't be allowed to add anymore after 3 times
string1 += 50;
string2 += 50;
jtf1 += 50;
jtf2 += 50;
cb1 += 50;
cb2 += 45;
//Would like to add the following components to the 'Panel' (which is a JPanel) whenever the JButton 'button' already added to 'Panel' is clicked.
p.add(jtf1); //Would doing p.add really add to the panel when the ActionListener is called?
jtf1.setBounds(60, yJtf1, 50, 40);
p.add(jtf2);
jtf2.setBounds(60, yJtf2, 50, 40);
add(jcb1);
jcb1.setBounds(250, cb1, 50, 40);
add(left2);
jcb2.setBounds(250, cb2, 50, 40);
Font font = new Font("TimesRoman", Font.BOLD, 18);
g.setFont(font); //Getting error on 'g' regardless
g.drawString("Hi", 15, string1); //This is the main problem, how would I be able to add this strings to the 'Panel' (which is a JPanel)
g.drawString("There", 330, string1);
}
count++;
}
});*/
add(jtf1);
jtf1.setBounds(100, 30, 120, 30);
add(jtf2);
ljtf2.setBounds(100, 60, 120, 30);
add(button);
plusButton.setBounds(200,150, 50, 50);
//button.addActionListener(new ButtonClicked()); if doing ActionListener via class like below
add(jcb1);
jcb1.setBounds(300, 350, 100, 50);
add(ljcb2);
jcb2.setBounds(300, 350, 100, 25);
Font font = new Font("Arial", Font.BOLD, 12);
g.setFont(font);
g.drawString("Item:", 40, 45);
g.drawString("Cost:", 40, 75);
}
}
public static void main(String [] args){
new Main();
}
class ButtonClicked implements ActionListener{ //Action Listener: The follow is what I am trying to implement
public void actionPerformed(ActionEvent ae){
if(count < 3){ //Won't be allowed to add anymore after 3 times
string1 += 50;
string2 += 50;
jtf1 += 50;
jtf2 += 50;
cb1 += 50;
cb2 += 45;
//Would like to add the following components to the 'Panel' (which is a JPanel) whenever the JButton 'button' already added to 'Panel' is clicked.
p.add(jtf1); //Would doing p.add really add to the panel when the ActionListener is called?
jtf1.setBounds(60, yJtf1, 50, 40);
p.add(jtf2);
jtf2.setBounds(60, yJtf2, 50, 40);
mp.add(jcb1);
jcb1.setBounds(250, cb1, 50, 40);
mp.add(left2);
jcb2.setBounds(250, cb2, 50, 40);
Font font = new Font("TimesRoman", Font.BOLD, 18);
g.setFont(font);
g.drawString("Hi", 15, string1); //This is the main problem, how would I be able to add this strings to the 'Panel' (which is a JPanel)
g.drawString("There", 330, string1);
}
count++;
}
}
}
我需要在ActionPerformed中使用paintComponent的图形g。“`
不,因为Swing graphics是被动的而不是主动的。Graphics对象将驻留在JPanel的paintComponent方法中,并且在它调用paintComponent方法时(而且只有它调用paintComponent方法)将从JVM传递给它。actionPerformed方法将更改字符串变量或ArrayList
的值,调用repaint()
,然后JPanel的paintComponent方法将使用更改后的字符串绘制适当的文本。
如果您需要更具体的帮助,可以考虑告诉我们更多的细节,并发布一个最小的示例程序。
编辑
我猜您真正想做的是,那可能是添加更多的组件,以允许用户在GUI中输入更多的数据。您还希望添加文本,可能是为了指导用户了解组件的用途。如果是这样,那么最好的解决方案不是在paintComponent中将字符串添加到GUI中,而是以有组织的方式添加字符串/组件,字符串显示在JLabels中,组件和标签都保存在一个或多个JPanels中,并使用布局管理器添加到GUI中。
例如,如果希望用户在两个JTextfields中添加数据,并拥有两个JComboBoxes,然后允许用户在需要时再添加3个这些家伙,则GUI可能如下所示:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
@SuppressWarnings("serial")
public class Main2 extends JPanel {
private List<DataPanel> dataPanelList = new ArrayList<>();
private JPanel dataPanelHolder = new JPanel();
public Main2() {
DataPanel dataPanel = new DataPanel();
dataPanelList.add(dataPanel);
setLayout(new BorderLayout());
dataPanelHolder.setLayout(new BoxLayout(dataPanelHolder, BoxLayout.PAGE_AXIS));
dataPanelHolder.add(dataPanel);
JPanel innerBorderLayoutPanel = new JPanel(new BorderLayout());
innerBorderLayoutPanel.add(dataPanelHolder, BorderLayout.PAGE_START);
JScrollPane scrollPane = new JScrollPane(innerBorderLayoutPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
int w = dataPanel.getPreferredSize().width;
int h = dataPanel.getPreferredSize().height * 4;
Dimension viewPortSize = new Dimension(w, h);
scrollPane.getViewport().setPreferredSize(viewPortSize);
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
buttonPanel.add(new JButton(new AddDatatAction("Add")));
buttonPanel.add(new JButton(new ExitAction("Exit", KeyEvent.VK_X)));
add(scrollPane, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.PAGE_END);
}
private class AddDatatAction extends AbstractAction {
private int maxCount = 4;
public AddDatatAction(String name) {
super(name);
int mnemonic = (int)name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
if (dataPanelList.size() < maxCount) {
DataPanel dataPanel = new DataPanel();
dataPanelList.add(dataPanel);
dataPanelHolder.add(dataPanel);
dataPanelHolder.revalidate();
dataPanelHolder.repaint();
}
}
}
private class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
Window win = SwingUtilities.getWindowAncestor(Main2.this);
win.dispose();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Main2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Main2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
@SuppressWarnings("serial")
class DataPanel extends JPanel {
private static final String[] TOOLS = {"Tool 1", "Tool 2", "Tool 3", "Tool 4"};
private static final String[] FIELD_LABELS = {"Item", "Cost"};
private static final String[] COMBO_LABELS = {"Foo", "Bar"};
private JTextField[] fields = new JTextField[FIELD_LABELS.length];
private List<JComboBox<String>> comboList = new ArrayList<>();
public DataPanel() {
setBorder(BorderFactory.createTitledBorder("Data"));
setLayout(new GridBagLayout());
for (int i = 0; i < FIELD_LABELS.length; i++) {
add(new JLabel(FIELD_LABELS[i]), createGbc(0, i));
fields[i] = new JTextField(10);
add(fields[i], createGbc(1, i));
JComboBox<String> combo = new JComboBox<>(TOOLS);
comboList.add(combo);
add(combo, createGbc(2, i));
add(new JLabel(COMBO_LABELS[i]), createGbc(3, i));
}
}
public static GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
int ins = 4;
gbc.insets = new Insets(ins, ins, ins, ins);
return gbc;
}
}
看起来可能是:
我必须插入一个JFrame,另一个类的一个JPanel。我在JFrame中有一个jMenuItem,我希望这样,当我单击jMenuItem,就会出现JPanel。
我为欢迎屏幕设计了一个接口,其中有一个JFrame,包括两个JPanel(JPanel1在右边,JPanel2在左边)。左边的按钮用于切换JPanel1中的面板。我想按下一个按钮,用另一个JPanel替换JPanel1内容,但我不知道怎么做。请帮忙。
我使用架构和堆栈。 对于服务之间的通信,我决定使用。 我有一个名为的服务,今天我实现了一个项目,并将其添加到存储库中。 我添加了到服务使用使用以下命令: 现在我想在中创建一个服务类,
我正试图创建一个员工工资单系统。我用JMenuItem创建了一个下拉菜单Add Employee,当您单击该菜单项时,它将在下面显示另一个jframe,以输入所有员工的详细信息。我有添加雇员JFrame,它运行完美。所以我想知道如何将两者联系起来?这是其中可能有所帮助的一部分
这里Book是根类,即最终的CSV将命名为books.CSV。 使用,我们只获得字段名title和author,但是我们还需要来自author类的字段名(name和age),有没有方法获得这些字段名?
我想在我的基本框架中添加一个带有JPanel的JScrollpane 如果我将带有的直接添加到中,就可以了。但是现在,当我将帧的大小减小到500像素以下时,变得更小,如第二张图片所示。 如何使JScrollPane工作?