Как предотвратить искажение и искажение панелей изображений в JScrollPane - PullRequest
3 голосов
/ 07 декабря 2011

Позвольте мне объяснить проект, который я создаю.Мне нужен список изображений, например, кинопленка, где я могу перетащить изображение из полосы в другую часть программы и что-то с этим делать.Это конечная цель, однако на данный момент я просто иду своим путем.Я создал FilmStripItem, который хранит информацию об изображении и отображает миниатюру изображения.Я пытаюсь создать FilmStripPanel, который представляет собой JScrollPane, который показывает каждую из миниатюр в форме оси Y.

Теперь я новичок в Java Swing и бьюсь головой о стенув течение нескольких недель пытаясь выяснить BorderLayout, BoxLayout, GridLayout и какой из них будет лучше.Кроме того, я не могу заставить их работать так, как я хочу.Ниже приведен код, который я использую (я избавился от ненужных деталей класса).В основном, что происходит, когда я запускаю FilmStripPanel, он сжимает все изображения, чтобы соответствовать размеру окна, и полоса прокрутки не отображается.Как я могу заставить его отображать изображения (80x80) без их сжатия?

FilmStripItem.java

//Removed import info to save space

public class FilmStripItem extends JPanel {
    private BufferedImage testImg;
    private Image thumbnail;

    public FilmStripItem(BufferedImage img) {
        this.testImg = img;
        this.thumbnail = img.getScaledInstance(80, 80, Image.SCALE_SMOOTH);

        JPanel p = new JPanel();
        p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
        p.setMinimumSize(new Dimension(80, 80));
        add(p);
    }

    public Image GetThumbnail() {
        return this.thumbnail;
    }

    @Override
    public void paintComponent(Graphics g) {
        g.drawImage(this.thumbnail, 0, 0, null);
    }

    public static void main(String[] ARGS) {
        try {
            //Removed look and layout info
        } catch (Exception ex) {
            Logger.getLogger("Demo").log(Level.WARNING,
                    "loading CuiLookAndFeel failed", ex);
        }
        JFrame f = new JFrame("FilmStripItem");
        final FilmStripItem fi = new FilmStripItem();
        f.setContentPane(fi);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setBounds(10, 10, 128, 128);
        f.setVisible(true);
    }
}

FilmStripPanel.java

//import info removed to save space

public class FilmStripPanel extends JPanel {
    private static final int ITEM_COUNT = 15;
    private ArrayList<FilmStripItem> filmItems;

    public FilmStripPanel() {
        JPanel p = new JPanel(new GridLayout(0, 1));
        setLayout(new GridLayout(1, 1));

        filmItems = new ArrayList<FilmStripItem>();
        JComponent[] c = new JComponent[ITEM_COUNT];

        for (int i = 0; i < ITEM_COUNT; i++) {
            FilmStripItem item = new FilmStripItem();
            filmItems.add(item);
            c[i] = item;
            p.add(c[i]);
        }

        JScrollPane sp = new JScrollPane(p, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        add(sp);
    }

    public static void main(String[] args) {
        try {
            //Removed look and feel info
        } catch (Exception ex) {
            Logger.getLogger("Demo").log(Level.WARNING,
                    "loading CuiLookAndFeel failed", ex);
        }
        JFrame f = new JFrame("FilmStrip");
        final FilmStripPanel p = new FilmStripPanel();
        f.setContentPane(p);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setBounds(10, 10, 128, 512);
        f.setVisible(true);
    }
}

Я гуглил дляэто снова и снова, но я не могу понять это для моей точной проблемы.Я уверен, что здесь есть какой-то избыточный код, и не стесняйтесь указывать на него.Я мог бы использовать всю помощь, которую вы, ребята, могли бы предложить, а также любую критику, я пытаюсь изучить Java Swing для работы, и у меня не получается.

Ответы [ 2 ]

4 голосов
/ 07 декабря 2011

Для простоты я бы сам отображал JList из ImageIcons.

Редактировать: у вас может быть карта для сопоставления маленьких изображений с большими (если большие не такие большие, чтобы вам не хватало памяти), а затем использовать ListSelectionListener, добавленный кJList, чтобы получить маленькую иконку, а затем карту, чтобы получить большую.Большой можно затем отобразить в JLabel.

Например:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

/**
 * Source of images: Wikimedia Commons
 * http://commons.wikimedia.org/wiki/Category:Small-sized_coats_of_arms
 * @author Pete
 *
 */
@SuppressWarnings("serial")
public class FilmStripEg extends JPanel {
   public static final String WIKIMEDIA_PATH = "http://upload.wikimedia.org/" +
        "wikipedia/commons/thumb/";
   public static final String WIKIMEDIA_COMMONS_PATH = "http://upload.wikimedia.org/" +
        "wikipedia/commons/";
   public static final String[] IMAGE_PATHS = {
         "d/d8/Amriswil.jpg/98px-Amriswil.jpg",
         "e/e3/Brot-plamboz.png/102px-Brot-plamboz.png",
         "e/ef/Cerneux-pequignot.png/103px-Cerneux-pequignot.png",
         "b/b6/Cham_zg.jpg/90px-Cham_zg.jpg",
         "1/13/Chaux-du-milieu.png/102px-Chaux-du-milieu.png",
         "c/c2/Diessenhofen.GIF/99px-Diessenhofen.GIF",
         "f/f0/Cressier.gif/100px-Cressier.gif",
         "8/8c/GW-GL-Glarus_Sued.png/100px-GW-GL-Glarus_Sued.png",
         "3/3d/GW-GL-Haetzingen.png/100px-GW-GL-Haetzingen.png",
         "d/de/GW-GR-Tomils.png/100px-GW-GR-Tomils.png",
         "e/e5/Montmollin.png/101px-Montmollin.png", 
         "7/73/GW-GL-Naefels.gif/100px-GW-GL-Naefels.gif",
         "3/3d/GW-NE-Val-de-Travers.png/104px-GW-NE-Val-de-Travers.png",
         "d/d9/Herdern.gif/102px-Herdern.gif",
         "3/35/Kesswil.GIF.gif/101px-Kesswil.GIF.gif",
         "0/00/Roche-vaud.jpg/105px-Roche-vaud.jpg",
         "d/da/S-blaise.png/107px-S-blaise.png", 
         "3/3d/Vaugondr.jpg/107px-Vaugondr.jpg"};

   private static final int PREF_W = 600;
   private static final int PREF_H = PREF_W;

   private DefaultListModel model = new DefaultListModel();
   private JList filmStripList = new JList(model);
   private JLabel imageLabel = new JLabel();
   private Map<ImageIcon, ImageIcon> iconMap = new HashMap<ImageIcon, ImageIcon>();

   public FilmStripEg() {
      JPanel centerPanel = new JPanel(new GridBagLayout());
      centerPanel.add(imageLabel);
      centerPanel.setBackground(Color.white);

      setLayout(new BorderLayout());
      add(new JScrollPane(filmStripList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.LINE_END);
      add(centerPanel, BorderLayout.CENTER);
      try {
         for (String smallImagePath : IMAGE_PATHS) {
            BufferedImage img = ImageIO.read(new URL(WIKIMEDIA_PATH + smallImagePath));
            ImageIcon smallIcon = new ImageIcon(img);
            model.addElement(smallIcon);

            String largeImagePath = WIKIMEDIA_COMMONS_PATH + smallImagePath.replaceAll("/\\d{1,3}px.*", "");
            BufferedImage largeImg = ImageIO.read(new URL(largeImagePath));
            ImageIcon largeIcon = new ImageIcon(largeImg);

            iconMap.put(smallIcon, largeIcon);
         }
      } catch (MalformedURLException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }

      filmStripList.addListSelectionListener(new ListSelectionListener() {
         public void valueChanged(ListSelectionEvent e) {
            if (e.getValueIsAdjusting()) {
               return;
            }
            ImageIcon icon = iconMap.get(filmStripList.getSelectedValue());
            imageLabel.setIcon(icon);
         }
      });

   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

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

      JFrame frame = new JFrame("FilmStripEg");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}
2 голосов
/ 07 декабря 2011

Думайте о панели прокрутки как о представлении ее содержимого. По умолчанию, в зависимости от макета, независимо от того, что вы поместите в панель прокрутки, он не будет знать, какой он должен быть. Поэтому он спрашивает своего родителя, насколько он должен быть большим, и родитель говорит: «Ну, я такой большой, так что просто будь таким большим». Если вы хотите убедиться, что полосы прокрутки используются, вы должны установить размер элемента внутри панели прокрутки.

Мое предложение будет таким: Создайте новый класс, расширяющий JPanel, который будет содержимым панели прокрутки (вместо p). В нем переопределите getPreferredSize() и вычислите требуемую высоту для всех изображений на панели и верните ее как высоту. Верните максимальную ширину любого 1 изображения в качестве ширины.

Подробнее о панели прокрутки см. В руководствах .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...