Не то, чтобы ваш ящик открывался автоматически. Это значит, что DrawerLayout
не находит View
для использования в качестве ящика, поэтому оба его прямого дочернего View
s заполняют его. LinearLayout
, предназначенный для того, чтобы быть выдвижным ящиком, который был указан последним, охватывает содержимое View
, поэтому просто появляется, что ящик открыт.
DrawerLayout
определяет, какие View
s использовать как ящики, просматривая его прямые дети для тех, у кого есть горизонтальная настройка layout_gravity
; то есть left
/ right
или start
/ end
. Вы хотите, чтобы этот атрибут был установлен на LinearLayout
, так как теперь он действует как ящик. В своем основном макете просто переместите android:layout_gravity="left"
с ListView
на LinearLayout
.
При вызове getImage слишком рано компонент еще не будет отображен и будет все еще иметь 0 ширин и высоту. Вы удостоверились, что называете его в достаточное последнее время? Попытайтесь печатать размер компонента к stdout и посмотрите, каковы его размеры.
Не называйте paintComponent () или краска () с внешней стороны. Вместо этого позвольте своему изображению быть созданным в рамках тех (перезаписанных) методов. Затем можно быть уверены, что изображение будет на самом деле содержать нарисованное содержание компонента.
Вот пример приложения. ImagePanel на самом деле захватит графическое содержание компонента каждый раз, когда это красится, который мог бы быть немного расточительным, таким образом, можно хотеть скорректировать частоту, с которой это сделано.
public class SomeApp extends JFrame {
private static class ImagePanel extends JPanel {
private BufferedImage currentImage;
public BufferedImage getCurrentImage() {
return currentImage;
}
@Override
public void paint(Graphics g) {
Rectangle tempBounds = g.getClipBounds();
currentImage = new BufferedImage(tempBounds.width, tempBounds.height, BufferedImage.TYPE_INT_ARGB);
super.paint(g);
super.paint(currentImage.getGraphics());
}
}
public SomeApp() {
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setSize(800,600);
int matrixSize = 4;
setLayout(new BorderLayout());
add(new JLabel("Wonderful Application"), BorderLayout.NORTH);
final ImagePanel imgPanel = new ImagePanel();
imgPanel.setLayout(new GridLayout(matrixSize,matrixSize));
for(int i=1; i<=matrixSize*matrixSize; i++) {
imgPanel.add(new JButton("A Button" + i));
}
add(imgPanel, BorderLayout.CENTER);
final JPanel buttonPanel = new JPanel();
buttonPanel.add(new JButton(new AbstractAction("get image") {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(SomeApp.this, new ImageIcon(imgPanel.getCurrentImage()));
}
}));
add(buttonPanel, BorderLayout.SOUTH);
}
public static void main(String[] args) {
System.setProperty("swing.defaultlaf", UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SomeApp().setVisible(true);
}
});
}
}
Как сказанный Martijn, Ваше изображение было, вероятно, черным, потому что компонент еще даже не красился/отображался. Вы могли добавить ComponentListener, который будет уведомлен, когда он отображен. Ваше "решение" с getSubimage не имеет никакого отношения к фактической проблеме. Я рекомендую удалить его.
Кажется, что проблема происходила из-за того, как BufferedImage был создан. При использовании:
BufferedImage hello = bufferedImage.getSubimage(0,0, getWidth(), getHeight());
Вместо этого это работало. Я также имел к переключателю от paintComponent для рисования для рендеринга детей.
Проблема решила, но если кто-либо знает. Почему сделал мой:
BufferedImage hello = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Всегда представляйте черное изображение? Offtopic, но могло быть интересно знать :)