Нужна помощь в отладке простого приложения Swing с помощью JLayeredPane

Я пытаюсь разработать приложение Swing, которое выглядит следующим образом:

(Демо для этого приложения можно найти здесь)

Черный квадрат перемещается при перемещении курсора. Запись ComboBox выбирает самый верхний слой в стеке, над которым квадрат будет отображаться во время движения, но ниже оставшихся следующих верхних слоев.

Я почти закончил, но черный квадрат (изображение) вибрирует, когда мышь перемещается (движение не плавное), а также его движение ограничено небольшой областью, и оно не перемещается по всей многослойной панели. Также нет никакого эффекта изменения настройки в ComboBox или CheckBox.

Вот код:-

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class JLayeredPaneDemo implements ActionListener, MouseMotionListener{
private String layerString[]={"Red(0)","Yellow(1)","Blue(2)","Green(3)","Orange(4)"};
private Color layerColors[]={Color.RED,Color.YELLOW,Color.BLUE,Color.GREEN,Color.ORANGE};
JComboBox jcb;
JCheckBox jcheck;
JLayeredPane layeredPane;
ImageIcon img;
JLabel cursor;

public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable(){public void run(){new JLayeredPaneDemo();}});
}

public JLayeredPaneDemo()
{
JFrame frame=new JFrame("JLayeredPane Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(2,1));

frame.add(createControlPanel());
//frame.add(Box.createRigidArea(new Dimension(0, 10)));
frame.add(createLayeredPane());

try
{
    img=new ImageIcon(ImageIO.read(new File("src/watermark.png")));
}catch(IOException e){System.out.println("ERROR LOADING IMAGE :"+ e);}
cursor=new JLabel(img);
cursor.setBounds(45,45,img.getIconWidth(),img.getIconHeight());
cursor.addMouseMotionListener(this);
layeredPane.add(cursor,new Integer(2),0);

frame.pack();
frame.setVisible(true);
}

public JPanel createControlPanel()
{
JPanel panel=new JPanel();
panel.setBorder(BorderFactory.createTitledBorder("Select the Settings"));

jcb=new JComboBox(layerString);
jcb.setSelectedIndex(0);
jcb.setActionCommand("LAYER_SETTING");
jcb.addActionListener(this);

jcheck=new JCheckBox();
jcheck.setSelected(true);
jcheck.setActionCommand("FRONT_BACK");
jcheck.addActionListener(this);

panel.add(jcb);
panel.add(jcheck);

return panel;
}

public JLayeredPane createLayeredPane()
{
layeredPane=new JLayeredPane();
layeredPane.setBorder(BorderFactory.createTitledBorder("Layered Pane : Move Your Mouse"));
layeredPane.setPreferredSize(new Dimension(300,310));

Point origin=new Point(20,20);
int offset=35;

for(int i=0;i<layerString.length;i++)
{
    JLabel label=createColoredLabel(layerString[i],layerColors[i],origin);
    layeredPane.add(label,new Integer[i]);
    origin.x+=offset;
    origin.y+=offset;
}

return layeredPane;
}

private JLabel createColoredLabel(String str,Color color,Point origin)
{
JLabel label =new JLabel(str);
label.setVerticalAlignment(JLabel.TOP);
label.setHorizontalAlignment(JLabel.CENTER);
label.setOpaque(true);
label.setBackground(color);
label.setForeground(Color.BLACK);
label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
label.setBounds(origin.x,origin.y,100,100);

return label;
}
public void actionPerformed(ActionEvent e)
{
String cmd=e.getActionCommand();
if(cmd.equals("LAYER_SETTING"))
{
    int position=jcheck.isSelected() ? 0 :1;
        layeredPane.setLayer(cursor,jcb.getSelectedIndex(),position);
}
else if(cmd.equals("FRONT_BACK"))
{
    if(jcheck.isSelected())
        layeredPane.moveToFront(cursor);
    else
        layeredPane.moveToBack(cursor);
}
}

@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
//Do nothing
}

@Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
cursor.setLocation(e.getX(),e.getY());
}
}

Пожалуйста, помогите мне найти проблему.

2 ответа

Ваш mouseMoved() реализация больше не применяет смещения, используемые в оригинале; вам нужно будет предоставить их на основе геометрии Icon используется в вашем cursor,

//Adjustments to put Duke's toe at the cursor's tip.
private static final int XFUDGE = 40;
private static final int YFUDGE = 57;
...
//Make Duke follow the cursor.
public void mouseMoved(MouseEvent e) {
    dukeLabel.setLocation(e.getX()-XFUDGE, e.getY()-YFUDGE);
}

Приложение: Я не понимаю, почему я не получил ошибку, когда использовал неправильные скобки?Может кто-нибудь указать причину, пожалуйста.

layeredPane.add(label,new Integer(i));

Поскольку язык определяет массив какObject, компилятор выбрал подходящее соответствиеadd() метод:

public void add(Component comp, Object constraints);

Есть две глупые ошибки, которые поглотили мои 11 драгоценных часов.

1) Я установил actionListener для "курсора" вместо LayeredPane, и поэтому движение было ограничено небольшой областью.

2) Во-вторых, я написал layeredPane.add(label,new Integer[i]); вместо layeredPane.add(label,new Integer(i)); (Обратите внимание на квадратные скобки).

Другие вопросы по тегам