我知道这种问题已在这里多次讨论,但我很困惑。我是Java的初学者,老实说,我不知道该怎么做,我承认我没有那么多时间阅读Oracle提供的整个文档。这是我的问题:
我正在尝试为我的程序编写GUI,以显示声波的干扰。数学功能在这里无关紧要。我有两个叫做Window和Sliders的类。 Window应该是一个'主GUI类',而Sliders应该从它继承(?)。
这来自我需要在Sliders类的Window和ChangeListener中实现ActionListener的另一个问题。我听说有一个班级不能实现几个班级,这就是为什么我做了两个班级。
现在,我写了两个类有点乱,但我不知道如何将它们组合起来。它真的很傻,但是在C ++之后我很困惑如何告诉程序它应该在一个框架中显示在Window类中定义的按钮和在Sliders类中定义的滑块。目前它只显示我想让它显示滑块的按钮。
对于混乱的伪代码我很抱歉,请帮忙。请尝试尽可能简单地解释。请随意忽略覆盖的方法,它们还没有完成。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
public class Window extends JFrame implements ActionListener
{
private JButton showChord, playSound, getSample, getPlot;
private JLabel chordInfo;
private JPanel basicFunctions;
public Window()
{
init();
}
private void init()
{
setVisible(true);
setSize(new Dimension(1000,500));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
basicFunctions = new JPanel();
FlowLayout basicLayout = new FlowLayout();
basicFunctions.setLayout(basicLayout);
showChord = new JButton("Akord");
playSound = new JButton("Odtwórz");
getSample = new JButton("Pobierz dźwięk");
getPlot = new JButton("Pobierz wykres");
showChord.addActionListener(this);
playSound.addActionListener(this);
getSample.addActionListener(this);
getPlot.addActionListener(this);
basicFunctions.add(showChord);
basicFunctions.add(playSound);
basicFunctions.add(getSample);
basicFunctions.add(getPlot);
add(basicFunctions);
Sliders param = new Sliders();
}
public static void main(String[] args)
{
Window frame = new Window();
}
//Action Listener
@Override
public void actionPerformed(ActionEvent a)
{
Object event = a.getSource();
if(event == showChord)
{
}
else if(event == playSound)
{
}
else if(event == getSample)
{
}
else if(event == getPlot)
{
}
}
}
import java.awt.*;
import javax.swing.event.ChangeEvent;
import javax.swing.*;
import javax.swing.event.ChangeListener;
public class Sliders extends Window implements ChangeListener
{
private JPanel sliders, sliderSub;
private JTextField accAmplitude, accFrequency, accPhase;
private JSlider amplitude, frequency, phase;
private double amplitudeValue, frequencyValue, phaseValue;
public Sliders()
{
sliders = new JPanel();
sliders.setLayout(new FlowLayout());
amplitude = new JSlider(0,100,0);
amplitude.setMajorTickSpacing(10);
amplitude.setMinorTickSpacing(5);
amplitude.setPaintTicks(true);
amplitude.setPaintLabels(true);
frequency = new JSlider(0,10,0);
frequency.setMajorTickSpacing(1);
frequency.setMinorTickSpacing(1/10);
frequency.setPaintTicks(true);
frequency.setPaintLabels(true);
phase = new JSlider(0,1,0);
phase.setMinorTickSpacing(2/10);
phase.setPaintTicks(true);
phase.setPaintLabels(true);
accAmplitude = new JTextField();
accFrequency = new JTextField();
accPhase = new JTextField();
sliders.add(amplitude, BorderLayout.NORTH);
sliders.add(frequency, BorderLayout.CENTER);
sliders.add(phase, BorderLayout.SOUTH);
add(sliders);
}
@Override
public void stateChanged(ChangeEvent arg0)
{
}
}
到目前为止我已经完成了这个,但是那些文本字段只是停止显示滑块值,我不知道为什么。它们在Parameters类和Window类中定义。有人可以帮忙吗?此外,我希望将来可以编辑这些文本字段,以便您可以通过在文本字段中键入来设置滑块值。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.event.*;
public class Window extends JPanel
{
private JMenuBar mainMenu = new JMenuBar();
private Plot plot = new Plot();
private Parameters param = new Parameters();
private JComboBox chooseChord = new JComboBox();
private JButton playSound = new JButton("Odtwórz");
private JButton getSample = new JButton("Pobierz dźwięk");
private JButton getPlot = new JButton("Pobierz wykres");
private JPanel mainPanel = new JPanel();
private JPanel subPanel = new JPanel();
private JPanel buttonsPanel = new JPanel();
private JPanel slidersPanel = new JPanel();
private JLabel chord = new JLabel("Akord:");
private JTextField aValue = new JTextField();
private JTextField fValue = new JTextField();
private JTextField pValue = new JTextField();
public Window()
{
mainPanel.setLayout(new FlowLayout());
buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.Y_AXIS));
slidersPanel.setLayout(new BorderLayout());
subPanel.setLayout(new BorderLayout());
chooseChord.addItem("A");
chooseChord.addItem("A#");
chooseChord.addItem("Ab");
chooseChord.addItem("B");
chooseChord.addItem("Bb");
chooseChord.addItem("C");
chooseChord.addItem("C#");
chooseChord.addItem("Cb");
chooseChord.addItem("D");
chooseChord.addItem("D#");
chooseChord.addItem("E");
chooseChord.addItem("F");
chooseChord.addItem("F#");
buttonsPanel.add(chord);
buttonsPanel.add(chooseChord);
buttonsPanel.add(Box.createRigidArea(new Dimension(0,10)));
buttonsPanel.add(playSound);
buttonsPanel.add(Box.createRigidArea(new Dimension(0,10)));
buttonsPanel.add(getSample);
buttonsPanel.add(Box.createRigidArea(new Dimension(0,10)));
buttonsPanel.add(getPlot);
buttonsPanel.setBorder(BorderFactory.createTitledBorder("Menu"));
slidersPanel.add(param);
JMenu langMenu = new JMenu("Język");
mainMenu.add(langMenu);
subPanel.add(buttonsPanel, BorderLayout.NORTH);
subPanel.add(slidersPanel, BorderLayout.SOUTH);
mainPanel.add(subPanel);
mainPanel.add(plot);
add(mainPanel);
param.addAmplitudeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent a)
{
double ampValue = param.getAmplitudeValue();
aValue.setText(String.valueOf(ampValue));
}
}
);
param.addFrequencyListener(new ChangeListener()
{
public void stateChanged(ChangeEvent f)
{
double frValue = param.getFrequencyValue();
fValue.setText(String.valueOf(frValue));
}
}
);
param.addPhaseListener(new ChangeListener()
{
public void stateChanged(ChangeEvent p)
{
double phValue = param.getPhaseValue();
pValue.setText(String.valueOf(phValue));
}
}
);
}
public JMenuBar getmainMenu()
{
return mainMenu;
}
private static void GUI()
{
Window mainPanel = new Window();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setJMenuBar(mainPanel.getmainMenu());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
GUI();
}
}
);
}
}
class Parameters extends JPanel
{
private JPanel pane = new JPanel();
private JPanel ampPanel = new JPanel();
private JPanel frPanel = new JPanel();
private JPanel phPanel = new JPanel();
private JSlider amplitude = new JSlider(0,100,0);
private JSlider frequency = new JSlider(0,10000,0);
private JSlider phase = new JSlider(0,180,0);
private JLabel pLabel = new JLabel("Faza");
private JLabel aLabel = new JLabel("Amplituda (dB)");
private JLabel fLabel = new JLabel("Częstotliwość (Hz)");
private JTextField preciseAmplitude = new JTextField(3);
private JTextField preciseFrequency = new JTextField(4);
private JTextField precisePhase = new JTextField(3);
public Parameters()
{
preciseAmplitude.setEditable(true);
preciseFrequency.setEditable(true);
precisePhase.setEditable(true);
pane.setLayout(new BoxLayout(pane, BoxLayout.PAGE_AXIS));
ampPanel.setLayout(new FlowLayout());
frPanel.setLayout(new FlowLayout());
phPanel.setLayout(new FlowLayout());
amplitude.setMajorTickSpacing(10);
amplitude.setMinorTickSpacing(5);
amplitude.setPaintTicks(true);
amplitude.setPaintLabels(true);
frequency.setMajorTickSpacing(2000);
frequency.setMinorTickSpacing(100);
frequency.setPaintTicks(true);
frequency.setPaintLabels(true);
phase.setMajorTickSpacing(2/10);
phase.setPaintTicks(true);
phase.setPaintLabels(true);
setBorder(BorderFactory.createTitledBorder("Parametry fali"));
ampPanel.add(aLabel);
ampPanel.add(preciseAmplitude);
pane.add(ampPanel);
pane.add(Box.createRigidArea(new Dimension(0,5)));
pane.add(amplitude);
pane.add(Box.createRigidArea(new Dimension(0,10)));
frPanel.add(fLabel);
frPanel.add(preciseFrequency);
pane.add(frPanel);
pane.add(Box.createRigidArea(new Dimension(0,5)));
pane.add(frequency);
pane.add(Box.createRigidArea(new Dimension(0,10)));
phPanel.add(pLabel);
phPanel.add(precisePhase);
pane.add(phPanel);
pane.add(Box.createRigidArea(new Dimension(0,5)));
pane.add(phase);
pane.add(Box.createRigidArea(new Dimension(0,10)));
add(pane);
}
public int getAmplitudeValue()
{
return amplitude.getValue();
}
public int getFrequencyValue()
{
return frequency.getValue();
}
public int getPhaseValue()
{
return phase.getValue();
}
public void addAmplitudeListener(ChangeListener ampListener)
{
amplitude.addChangeListener(ampListener);
}
public void addFrequencyListener(ChangeListener frListener)
{
frequency.addChangeListener(frListener);
}
public void addPhaseListener(ChangeListener phListener)
{
phase.addChangeListener(phListener);
}
}
class Plot extends JPanel
{
private JPanel componentWave = new JPanel();
private JPanel netWave = new JPanel();
private JLabel componentLabel = new JLabel("Fale składowe");
private JLabel netLabel = new JLabel("Fala wypadkowa");
private JLabel wave = new JLabel("Wybierz falę składową");
private JPanel labels = new JPanel();
private JComboBox chooseWave = new JComboBox();
public Plot()
{
labels.setLayout(new BoxLayout(labels, BoxLayout.PAGE_AXIS));
componentWave.setBackground(new Color(255,255,255));
netWave.setBackground(new Color(255,255,255));
componentWave.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
netWave.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
componentWave.setPreferredSize(new Dimension(400,200));
netWave.setPreferredSize(new Dimension(400,200));
labels.add(wave);
labels.add(Box.createRigidArea(new Dimension(0,10)));
labels.add(chooseWave);
labels.add(componentLabel);
labels.add(componentWave);
labels.add(Box.createRigidArea(new Dimension(0,20)));
labels.add(netLabel);
labels.add(netWave);
add(labels);
}
}
答案 0 :(得分:1)
Window旨在成为一个主要的GUI类'和滑块应该从它继承(?)。
Nope:这是对继承的滥用,只会导致问题,因为Sliders固有的Windows实例与显示的Windows实例完全不同。你需要做的是传递参考。
例如,以下代码使用JButton和JMenuItem Actions的外部类(Actions类似于类固醇上的ActionListeners),并使用一个包含JSlider的类,该类允许其类将侦听器附加到滑块。
import java.awt.Component;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Foo extends JPanel {
private static final long serialVersionUID = 1L;
private Action helloAction = new HelloAction("Hello", KeyEvent.VK_H);
private Action exitAction = new ExitAction("Exit", KeyEvent.VK_X);
private JMenuBar menuBar = new JMenuBar();
private JTextField sliderValueField = new JTextField(10);
private Bar bar = new Bar();
public Foo() {
sliderValueField.setEditable(false);
sliderValueField.setFocusable(false);
add(new JButton(helloAction));
add(new JButton(exitAction));
add(new JLabel("Slider Value: "));
add(sliderValueField);
add(bar);
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic(KeyEvent.VK_F);
fileMenu.add(new JMenuItem(exitAction));
fileMenu.add(new JMenuItem(helloAction));
menuBar.add(fileMenu);
bar.addSliderListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int sliderValue = bar.getSliderValue();
sliderValueField.setText(String.valueOf(sliderValue));
}
});
}
public JMenuBar getJMenuBar() {
return menuBar;
}
private static void createAndShowGui() {
Foo mainPanel = new Foo();
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.setJMenuBar(mainPanel.getJMenuBar());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class HelloAction extends AbstractAction {
public HelloAction(String name, int mnemonic) {
super(name); // sets name property and gives button its title
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "Hello!");
}
}
class ExitAction extends AbstractAction {
private static final long serialVersionUID = 1L;
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
Component component = (Component) e.getSource();
Window win = SwingUtilities.getWindowAncestor(component);
if (win == null) {
// if no window, then a JMenuItem held in a JPopupMenu
JPopupMenu popup = (JPopupMenu) component.getParent();
component = popup.getInvoker();
win = SwingUtilities.getWindowAncestor(component);
}
win.dispose();
}
}
class Bar extends JPanel {
private JSlider slider = new JSlider(0, 100, 50);
public Bar() {
slider.setPaintLabels(true);
slider.setPaintTicks(true);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(5);
slider.setSnapToTicks(true);
setBorder(BorderFactory.createTitledBorder("Slider Panel"));
add(slider);
}
public int getSliderValue() {
return slider.getValue();
}
// one way to let outside classes listen for changes
public void addSliderListener(ChangeListener listener) {
slider.addChangeListener(listener);
}
}
你问小数标签,是的,这可以做,但需要使用标签表。例如,
JSlider slider = new JSlider(0, 100, 50);
slider.setPaintLabels(true);
slider.setPaintTicks(true);
slider.setMajorTickSpacing(20);
slider.setMinorTickSpacing(2);
Dictionary<Integer, JLabel> labels = new Hashtable<>();
for (int i = 0; i <= 100; i += 20) {
labels.put(i, new JLabel(String.format("%.1f", i / 200.0)));
}
slider.setLabelTable(labels);
显示为:
您还必须将值从int转换回相应的浮点数。