2017-02-21 32 views
0

Я пытаюсь заставить этот код работать, так что у меня есть контейнер cardlayout, и каждая панель определяется в своем собственном классе и фактическом файле. Этот код не на 100% мой собственный и является модифицированной версией моего предыдущего материала другим пользователем переполнения стека. Это более или менее то, что мне нужно, но мне оно нужно, чтобы оно не было автоматизировано, и я могу написать 15 разных панелей с решениями, принимаемыми внутри каждого из них. Класс Main и Arrow был изменен указанным пользователем, а Imagepanel - моя попытка написать класс, который будет принят рабочей частью кода. Проблема заключается в том, что вкладка Imagepanel I в контейнер будет регистрироваться как существующая, но на панели ничего не отображается, она пустая. Отмеченная часть в ImagePanel - это мой код, который я установил на задний план в пользу установленного материала, ранее использовавшегося в классе Arrow.Java Swing CardLayout несколько файлов

Вот Основной класс

import java.awt.BorderLayout; 
import java.awt.CardLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.GridBagLayout; 
import java.awt.event.ActionEvent; 
import java.awt.*; 
import javax.swing.*; 

public class Main extends JPanel { 
    private Arrow arrow = new Arrow(); //creates a new Arrow object 

public Main() { 
    JPanel btnPanel = new JPanel(); 
    btnPanel.add(new JButton(new NextAction("Next")));  

    setLayout(new BorderLayout()); 
    add(arrow, BorderLayout.NORTH); 
    add(btnPanel, BorderLayout.PAGE_END); 
} 

private class NextAction extends AbstractAction { 
    public NextAction(String name) { 
     super(name); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     arrow.next(); // *** call arrow's public next method that you created 

     // no need to make a new CardLayout instance 
    } 
} 

private static void createAndShowGui() { 
    Main mainPanel = new Main(); 

    JFrame frame = new JFrame("Iowa Budget Simulation"); 
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    frame.getContentPane().add(mainPanel); 
    frame.pack(); 
    frame.setLocationByPlatform(true); 
    frame.setVisible(true); 
} 

public static void main(String[] args) { 
    SwingUtilities.invokeLater(() -> createAndShowGui()); 
} 

}

Вот класс Стрелка, где контейнер создается

import java.awt.BorderLayout; 
import java.awt.CardLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.GridBagLayout; 

import javax.swing.*; 

class Arrow extends JPanel { 
    private static final long serialVersionUID = 1L; 
    private CardLayout cardLayout = new CardLayout();  // make me a field 
    private JPanel cardHolder = new JPanel(cardLayout);  //creates a master JPanel 

public Arrow() { 
    for (int i = 0; i < 5; i++) { 
     cardHolder.add(createCard(i), "card " + i); 
    } 
    ImagePanel pear = new ImagePanel(); 
    cardHolder.add(pear, "Pear"); 
    setLayout(new BorderLayout()); 
    add(cardHolder, BorderLayout.NORTH); 

} 

// public method that other objects can call 
public void next() { 
    cardLayout.next(cardHolder); // call next on the correct object 
} 

// simply creates a "pretty" new JPanel 
private JComponent createCard(int i) { 
    JLabel label = new JLabel("Card " + i); 
    label.setFont(label.getFont().deriveFont(Font.BOLD, 50f)); 

    float h = (float)Math.random(); 
    Color c = Color.getHSBColor(h, 1f, 1f); 
    label.setForeground(c.darker()); 

    JPanel panel = new JPanel(new GridBagLayout()); 
    panel.add(label); 
    panel.setBorder(BorderFactory.createLineBorder(c.darker(), 20)); 
    panel.setBackground(c.brighter().brighter()); 

    panel.setPreferredSize(new Dimension(400, 300)); 
    return panel; 
} 

Вот ImagePanel, моя попытка на 3, индивидуальная панель/класс

import java.awt.BorderLayout; 
import java.awt.CardLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Font; 
import java.awt.GridBagLayout; 

import javax.swing.*; 

class ImagePanel extends JPanel { 

    private static final long serialVersionUID = 1L; 
    private String imgString; 
    private JLabel imgLabel; 

public JComponent ImagePanel() { 
    /* 
    setName("Pear"); 
    JLabel john = new JLabel("Pear"); 

    float h = (float)Math.random(); 
    Color c = Color.getHSBColor(h, 1f, 1f); 
    john.setForeground(c.darker()); 

    JPanel panel = new JPanel(new GridBagLayout()); 
    panel.add(john); 
    panel.setBorder(BorderFactory.createLineBorder(c.darker(), 20)); 
    panel.setBackground(c.brighter().brighter()); 
    // Ensure size is correct even before any image is loaded. 
    setPreferredSize(new Dimension(400, 300)); 
    return panel; 
    */ 

    JLabel label = new JLabel("Pear"); 
    label.setFont(label.getFont().deriveFont(Font.BOLD, 50f)); 

    float h = (float)Math.random(); 
    Color c = Color.getHSBColor(h, 1f, 1f); 
    label.setForeground(c.darker()); 

    JPanel panel = new JPanel(new GridBagLayout()); 
    panel.add(label); 
    panel.setBorder(BorderFactory.createLineBorder(c.darker(), 20)); 
    panel.setBackground(c.brighter().brighter()); 

    panel.setPreferredSize(new Dimension(400, 300)); 
    return panel; 
} 

Нет сообщений об ошибке, просто отображается пустая панель. Благодарим вас за любую помощь, которую я могу получить, и заранее извиняюсь за то, что изучаю GUI Java Swing через YouTube и переполнение стека.

+0

'ImagePanel()' не будет ничего делать (это создаст пустой компонент), вместо этого, изменить 'общественного JComponent ImagePanel() {' 'для общественного ImagePanel() {', так что вы теперь конструктор. Удалите 'JPanel panel = новый JPanel (новый GridBagLayout());' и просто вызовите 'setLayout (новый GridBagLayout());' и удалим другие ссылки на 'panel', и он должен начать работать – MadProgrammer

ответ

2

public JComponent ImagePanel() { не является конструктором, это метод, чтобы заставить его работать в коде, вам нужно было бы изменить ImagePanel pear = new ImagePanel(); на JComponent pear = new ImagePanel().ImagePanel();, но, откровенно говоря, это просто не имеет смысла.

Вместо этого, изменить public JComponent ImagePanel() { к public ImagePanel() {, теперь это конструктор класса

Далее, изменение ...

JPanel panel = new JPanel(new GridBagLayout()); 
panel.add(label); 
panel.setBorder(BorderFactory.createLineBorder(c.darker(), 20)); 
panel.setBackground(c.brighter().brighter()); 

panel.setPreferredSize(new Dimension(400, 300)); 
return panel; 

в

setLayout(new GridBagLayout()); 
add(label); 
setBorder(BorderFactory.createLineBorder(c.darker(), 20)); 
setBackground(c.brighter().brighter()); 

//panel.setPreferredSize(new Dimension(400, 300)); 
//return panel; 

Не заводи меня почему setPreferredSize это плохая идея

Теперь вы можете просто использовать

ImagePanel pear = new ImagePanel(); 
cardHolder.add(pear, "Pear"); 
+0

Чтобы объяснить, почему использование' setPreferredSize () 'является ba ... неразумной идеей: http://stackoverflow.com/a/26828479/1368690. В основном, когда вы используете 'setPreferredSize()', вы не позволяете компоненту вычислить точный размер, который ему нужен, что может привести к порезанию частей или дополнительной комнаты. – hamena314

+1

@ hamena314 Спасибо, я знаю, это не значит, что это «плохо» или «неразумно», но это злоупотребление без мысли, а переопределение «getPreferredSize» - это, как правило, лучший выбор, поскольку контейнер обычно лучше разбирается в том, сколько места ему нужно – MadProgrammer