2015-03-14 2 views
0

Я знаю, что этот вопрос обсуждался здесь много раз, но я в замешательстве. Я полностью новичок в Java, и я честно не знаю, что делать, и я признаю, что у меня не так много времени, чтобы прочитать всю документацию, предоставленную Oracle. Вот моя проблема:Метод вызова из одного класса в другом

Я пытаюсь запрограммировать GUI для моей программы, которая будет показывать интерференцию акустических волн. Математическая функциональность здесь не имеет значения. У меня есть два класса под названием «Окно и ползунки». Окно предназначено для «основного GUI-класса», и Sliders должен наследовать (?) От него.

Это связано с другой проблемой, которую мне нужно реализовать ActionListener в классе Window и ChangeListener в классе ползунков. Я слышал, что один класс не может реализовать несколько классов, поэтому я сделал два.

Теперь я написал немного хаотичный эти два класса, но я не знаю, как их объединить. Это действительно глупо, но после C++ я довольно смущен, как сообщить программе, что она должна показывать в одном кадре либо кнопки, определенные в классе Window, так и слайдеры, определенные в классе ползунков. В настоящее время он показывает только кнопки, которые я хочу сделать, показывая ползунки.

Мне очень жаль хаотический псевдокод, пожалуйста, помогите. Пожалуйста, попробуйте объяснить как можно проще/возможно. Пожалуйста, не стесняйтесь игнорировать переопределенные методы, они еще не закончены.

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) 
{ 


} 
} 

Я сделал это до сих пор, но эти текстовые поля просто перестали показывать значения слайдеров, и я не знаю, почему. Они определены в классе «Параметры» и «Окно». Может кто-нибудь помочь? Кроме того, в будущем я хотел бы сделать эти текстовые поля доступными для редактирования, чтобы вы могли установить значение ползунка, введя его в текстовое поле.

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

ActionListener и ChangeListener - это интерфейсы, а не классы, и поэтому вы можете реализовать (не наследовать) любое их число. – m0skit0

+2

** Но, как правило, ваш класс представления, графические интерфейсы, не должен реализовывать интерфейсы прослушивателя, поскольку это требует, чтобы представление делало слишком много, так как класс нарушил «правило единой ответственности» –

+0

. Как я могу реализовать больше, чем один интерфейс? Это было бы хорошо со мной, но проблема в другом. Написание одноклассных программ все время не имеет смысла, мне нужно научиться сочетать многие классы в Java. Я предполагаю, что «Единое правило ответственности» очень важно, но у меня нет идеи, как написать мою первую программу, которая выполнила бы это требование. – Colonder

ответ

1

Окно предназначено быть «основной класс GUI» и ползунки должен наследовать (?) От него.

Nope: это ненадлежащее использование наследования и приведет только к проблемам, поскольку экземпляр Windows, из которого состоит Ползунок, полностью отличается от отображаемого экземпляра Windows. Что вам нужно сделать, так это передать ссылки.

Например, следующий код использует внешние классы для действий JButton и JMenuItem (действия подобны 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); 

Который показывает, как:

enter image description here

Вы также должны перевести значение обратно из INT в соответствующем число с плавающей точкой.

+0

Еще один вопрос: существует ли какой-либо возможный способ сделать небольшие тики в слайдере, которые являются десятичными стоимость? Я имею в виду 0,1, 0,2 и т. Д. – Colonder

+0

@Colonder: да, но тогда вам нужно будет установить ярлык JSlider с помощью метода setLabelTable (...). –

+0

@Colonder: см. Править для ответа. –

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