JPanel里面的一个JPanel里面有一个JScrollPane,无法滚动

时间:2014-12-13 21:08:53

标签: java jframe jpanel

我将JPanel包装在JScrollPane中,并且我正在创建使用JPanel的项目实例,但是当我将这些放入JScrollPane中包含的JPanel时,JScrollPane将不允许我滚动。

图像: http://i.gyazo.com/a276cd66e4ecd3473698b85dec0c4b7c.png

这是我店铺商品的代码:

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.UIManager;
import java.awt.Color;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JTextPane;

public class ShopItem extends JPanel {

        private JPanel shopItemPanel;
        private JPanel panelPlaced;
        private JButton btnPurchase;
        private JLabel priceLabel;
        private JTextPane descPane;
        private JLabel attrLabel;
        private TitledBorder titledBorder;

        private int posX;
        private int posY;
        private int shopCatId;
        private int itemId;
        private String itemName;
        private int price;
        private String attribute;
        private int owned;
        private String description;
        private JLabel ownedLabel;

        public ShopItem(int posX, int posY, JPanel panelPlaced, int shopCatId, int itemId, String itemName, int price, String attribute, int owned, String description) {
                this.setPosX(posX);
                this.setPosY(posY);
                this.shopCatId = shopCatId;
                this.itemId = itemId;
                this.itemName = itemName;
                this.price = price;
                this.attribute = attribute;
                this.owned = owned;
                this.description = description;

                shopItemPanel = new JPanel();
                titledBorder = new TitledBorder(UIManager.getBorder("TitledBorder.border"), this.itemName, TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0));
                shopItemPanel.setBorder(titledBorder);
                shopItemPanel.setBounds(posX, posY, 170, 253);
                shopItemPanel.setLayout(null);

                btnPurchase = new JButton("Purchase");
                btnPurchase.setBounds(40, 219, 89, 23);
                shopItemPanel.add(btnPurchase);

                priceLabel = new JLabel("Price: $"+this.price);
                priceLabel.setBounds(10, 21, 147, 14);
                shopItemPanel.add(priceLabel);

                descPane = new JTextPane();
                descPane.setEditable(false);
                descPane.setBounds(10, 93, 147, 115);
                descPane.setText(this.description);
                shopItemPanel.add(descPane);

                attrLabel = new JLabel("Att: "+this.attribute);
                attrLabel.setBounds(10, 46, 150, 14);
                shopItemPanel.add(attrLabel);

                ownedLabel = new JLabel("Owned: "+this.owned);
                ownedLabel.setBounds(10, 71, 150, 14);
                shopItemPanel.add(ownedLabel);

                panelPlaced.repaint();
        }

        public void remove() {
                Shop.getShopItems().remove(this);
                this.panelPlaced.remove(this.shopItemPanel);
                this.panelPlaced.repaint();
        }

        public int getPrice() {
                return price;
        }

        public void setPrice(int price) {
                this.price = price;
        }

        public String getAttribute() {
                return attribute;
        }

        public void setAttribute(String attribute) {
                this.attribute = attribute;
        }

        public int getOwned() {
                return owned;
        }

        public void setOwned(int owned) {
                this.owned = owned;
        }

        public String getDescription() {
                return description;
        }

        public void setDescription(String description) {
                this.description = description;
        }

        public String getItemName() {
                return itemName;
        }

        public void setItemName(String itemName) {
                this.itemName = itemName;
        }

        public int getItemId() {
                return itemId;
        }

        public void setItemId(int itemId) {
                this.itemId = itemId;
        }

        public int getShopCatId() {
                return shopCatId;
        }

        public void setShopCatId(int shopCatId) {
                this.shopCatId = shopCatId;
        }

        public JPanel getPanelPlaced() {
                return panelPlaced;
        }

        public void setPanelPlaced(JPanel panelPlaced) {
                this.panelPlaced = panelPlaced;
        }

        public JPanel getShopItemPanel() {
                return shopItemPanel;
        }

        public void setShopItemPanel(JPanel shopItemPanel) {
                this.shopItemPanel = shopItemPanel;
        }

        public int getPosX() {
                return posX;
        }

        public void setPosX(int posX) {
                this.posX = posX;
        }

        public int getPosY() {
                return posY;
        }

        public void setPosY(int posY) {
                this.posY = posY;
        }

        public TitledBorder getTitledBorder() {
                return titledBorder;
        }

        public void setTitledBorder(TitledBorder titledBorder) {
                this.titledBorder = titledBorder;
        }
}

1 个答案:

答案 0 :(得分:2)

我没有看到您在已发布的代码中向JScrollPane添加任何内容,但我确实看到了大量setBounds(...)次调用以及{{ 1}},意味着您正在设置组件的绝对大小,这将阻止组件在JScrollPane内部正确扩展。解决方案:不要这样做。使用布局管理器,避免使用null布局。

你应该避免使用null布局,因为这会使非常不灵活的GUI,虽然它们在一个平台上看起来不错,但在大多数其他平台或屏幕分辨率上看起来很糟糕,并且很难更新和维护。 / p>

例如,考虑创建一个使用setLayout(null)的内部JPanel - 它代表一行和可变列,并且我将我的测试商店JPanels添加到其中。然后我将这个内部JPanel添加到JScrollPane,并在需要时将我的测试商店JPanels添加到其中,在每次添加后调用GridLayout(1, 0)revalidate()

其他建议:

  • 您将模型与视图混合在一起。考虑创建一个非GUI类,比如称为ShopItem,其中没有任何GUI,它具有任何ShopItem对象的关键逻辑字段,例如:repaint()字段。
  • 考虑创建一个GUI类,它保存并显示一个ShopItem对象,可能称为ShopItemView,它可以扩展或轻松返回JPanel,它可以显示ShopItem对象的所有数据,允许用户使用不同的方法设置它ShopItem对象,从而改变视图。
  • JTextAreas比JTextPanes更容易使用,因此如果显示的文本不需要任何花哨的东西,如果所有内容都以相同的字体显示,那么我将使用JTextArea,并且我设置了它的列和行属性,而不是它的边界或大小。
  • 我将文本组件包装在自己的JScrollPane中,无论它是JTextArea还是JTextPane。
  • 如果使用JTextArea,我会在其上调用int shopCatId, int itemId, String itemName, int price, String attribute, int owned, String descriptionsetLineWrap(true),以便自动换行文字。