我遇到了问题,无法解决。我正在创建一个包含多个JFrame的程序,并希望弹出窗口显示为Android的Toast。我找到了一个可以帮助我做到这一点的课程。该类有一个方法,它采用JFrame的位置来创建Toast。问题是,当我单独运行JFrame时,Toast工作正常,但是当我运行完整程序时,JFrame调用另一个JFrame的按钮,获取JFrame位置以创建Toast的方法显示NullPointerException,如作为参数指定的JFrame为null。所以无法获得位置,但单独工作。怎么了?谁能帮助我?感谢。
Toast代码:
public class Toast extends JDialog {
private static final long serialVersionUID = -1602907470843951525L;
public enum Style {
NORMAL, SUCCESS, ERROR
};
public static final int LENGTH_SHORT = 3000;
public static final int LENGTH_LONG = 6000;
public static final Color ERROR_RED = new Color(121, 0, 0);
public static final Color SUCCESS_GREEN = new Color(22, 127, 57);
public static final Color NORMAL_BLACK = new Color(0, 0, 0);
private final float MAX_OPACITY = 0.8f;
private final float OPACITY_INCREMENT = 0.05f;
private final int FADE_REFRESH_RATE = 20;
private final int WINDOW_RADIUS = 15;
private final int CHARACTER_LENGTH_MULTIPLIER = 7;
private final int DISTANCE_FROM_PARENT_TOP = 100;
private JFrame mOwner;
private String mText;
private int mDuration;
private Color mBackgroundColor = Color.BLACK;
private Color mForegroundColor = Color.WHITE;
public Toast(JFrame owner) {
super(owner);
mOwner = owner;
}
private void createGUI() {
setLayout(new GridBagLayout());
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
setShape(new RoundRectangle2D.Double(0, 0, getWidth(),
getHeight(), WINDOW_RADIUS, WINDOW_RADIUS));
}
});
setAlwaysOnTop(true);
setUndecorated(true);
setFocusableWindowState(false);
setModalityType(ModalityType.MODELESS);
setSize(mText.length() * CHARACTER_LENGTH_MULTIPLIER, 25);
getContentPane().setBackground(mBackgroundColor);
JLabel label = new JLabel(mText);
label.setForeground(mForegroundColor);
add(label);
}
public void fadeIn() {
final Timer timer = new Timer(FADE_REFRESH_RATE, null);
timer.setRepeats(true);
timer.addActionListener(new ActionListener() {
private float opacity = 0;
@Override
public void actionPerformed(ActionEvent e) {
opacity += OPACITY_INCREMENT;
setOpacity(Math.min(opacity, MAX_OPACITY));
if (opacity >= MAX_OPACITY) {
timer.stop();
}
}
});
setOpacity(0);
timer.start();
setLocation(getToastLocation());
setVisible(true);
}
public void fadeOut() {
final Timer timer = new Timer(FADE_REFRESH_RATE, null);
timer.setRepeats(true);
timer.addActionListener(new ActionListener() {
private float opacity = MAX_OPACITY;
@Override
public void actionPerformed(ActionEvent e) {
opacity -= OPACITY_INCREMENT;
setOpacity(Math.max(opacity, 0));
if (opacity <= 0) {
timer.stop();
setVisible(false);
dispose();
}
}
});
setOpacity(MAX_OPACITY);
timer.start();
}
private Point getToastLocation() {
System.out.println(mOwner);
Point ownerLoc = mOwner.getLocation();
int x = (int) (ownerLoc.getX() + ((mOwner.getWidth() - this.getWidth()) / 2));
int y = (int) (ownerLoc.getY() + DISTANCE_FROM_PARENT_TOP);
return new Point(x, y);
}
public void setText(String text) {
mText = text;
}
public void setDuration(int duration) {
mDuration = duration;
}
@Override
public void setBackground(Color backgroundColor) {
mBackgroundColor = backgroundColor;
}
@Override
public void setForeground(Color foregroundColor) {
mForegroundColor = foregroundColor;
}
public static Toast makeText(JFrame owner, String text) {
return makeText(owner, text, LENGTH_SHORT);
}
public static Toast makeText(JFrame owner, String text, Style style) {
return makeText(owner, text, LENGTH_SHORT, style);
}
public static Toast makeText(JFrame owner, String text, int duration) {
return makeText(owner, text, duration, Style.NORMAL);
}
public static Toast makeText(JFrame owner, String text, int duration,
Style style) {
Toast toast = new Toast(owner);
toast.mText = text;
toast.mDuration = duration;
if (style == Style.SUCCESS)
toast.mBackgroundColor = SUCCESS_GREEN;
if (style == Style.ERROR)
toast.mBackgroundColor = ERROR_RED;
if (style == Style.NORMAL)
toast.mBackgroundColor = NORMAL_BLACK;
return toast;
}
public void display() {
new Thread(new Runnable() {
@Override
public void run() {
try {
createGUI();
fadeIn();
Thread.sleep(mDuration);
fadeOut();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
}
JFrame代码:
public class MenuAtendente extends JFrame {
private JPanel contentPane;
private static JLabel lblInfo;
static MenuAtendente frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new MenuAtendente();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public MenuAtendente() {
setTitle("SGTA - <Nome da Academia>");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JFrame teste = frame;
setBounds(100, 100, 663, 449);
setLocationRelativeTo(null);
setResizable(false);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblMenuAtendente = new JLabel("Menu Atendente");
lblMenuAtendente.setFont(new Font("Tahoma", Font.PLAIN, 17));
lblMenuAtendente.setBounds(22, 11, 165, 28);
contentPane.add(lblMenuAtendente);
JButton btnCadastrarAluno = new JButton("Cadastrar Novo Aluno");
btnCadastrarAluno.setBounds(10, 75, 213, 84);
contentPane.add(btnCadastrarAluno);
btnCadastrarAluno.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
CadastroAlunosForm tela;
try {
tela = new CadastroAlunosForm();
tela.setVisible(true);
setVisible(false);
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
JButton btnPerfilDeAlunos = new JButton("Perfil de Alunos");
btnPerfilDeAlunos.setBounds(10, 172, 170, 84);
contentPane.add(btnPerfilDeAlunos);
btnPerfilDeAlunos.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
PerfilUsuario tela = new PerfilUsuario();
tela.setVisible(true);
setVisible(false);
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
JButton btnRelatoriosDeAluno = new JButton("Relat\u00F3rios de Alunos");
btnRelatoriosDeAluno.setBounds(10, 277, 225, 84);
contentPane.add(btnRelatoriosDeAluno);
btnRelatoriosDeAluno.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(frame);
Toast.makeText(frame, "Olá", Style.SUCCESS).display();
}
});
JButton btnLogout = new JButton("Logout");
btnLogout.setBounds(419, 17, 89, 23);
contentPane.add(btnLogout);
btnLogout.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
SessaoUsuario.getInstancia().setUsuarioLogado(null);
Login tela = new Login();
tela.setVisible(true);
dispose();
}
});
lblInfo = new JLabel("");
lblInfo.setBounds(10, 386, 581, 14);
contentPane.add(lblInfo);
JButton button = new JButton("Alterar Cadastro Aluno");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
AlterarCadastroAlunosForm tela;
try {
tela = new AlterarCadastroAlunosForm();
tela.setVisible(true);
dispose();
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
button.setBounds(267, 75, 177, 84);
contentPane.add(button);
}
public static void getLblInfo(String mensagem) {
lblInfo.setText(mensagem);
}
}
答案 0 :(得分:0)
您始终可以使用SwingUtilities.getWindowAncestor(component)
获取所显示组件的父级顶级窗口。例如
Window win = SwingUtilities.getWindowAncestor(someComponent);
Point ownerLoc = win.getLocation();
顺便说一下,
null
布局和setBounds(...)
是危险的代码,最终可能会咬你。您最好使用布局管理器来帮助您组织组件的位置和大小。修改强> 到目前为止,我尝试使用您的代码制作一个最小的示例程序:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.*;
import java.awt.geom.RoundRectangle2D;
import javax.swing.*;
import javax.swing.border.*;
public class FooGui {
public static void main(String[] args) {
MenuAtendente.main(args);
}
}
@SuppressWarnings("serial")
class MenuAtendente extends JFrame {
private JPanel contentPane;
private static JLabel lblInfo;
static MenuAtendente frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new MenuAtendente();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public MenuAtendente() {
setTitle("SGTA - <Nome da Academia>");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 663, 449);
setLocationRelativeTo(null);
setResizable(false);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null); // *** ugh, don't do this.
JButton btnRelatoriosDeAluno = new JButton("Relat\u00F3rios de Alunos");
btnRelatoriosDeAluno.setBounds(10, 277, 225, 84);
contentPane.add(btnRelatoriosDeAluno);
btnRelatoriosDeAluno.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//!!
System.out.println(frame);
Toast.makeText(frame, "Olá", Toast.Style.SUCCESS).display();
}
});
}
public static void getLblInfo(String mensagem) {
lblInfo.setText(mensagem);
}
}
class Toast extends JDialog {
private static final long serialVersionUID = -1602907470843951525L;
public enum Style {
NORMAL, SUCCESS, ERROR
};
public static final int LENGTH_SHORT = 3000;
public static final int LENGTH_LONG = 6000;
public static final Color ERROR_RED = new Color(121, 0, 0);
public static final Color SUCCESS_GREEN = new Color(22, 127, 57);
public static final Color NORMAL_BLACK = new Color(0, 0, 0);
private final float MAX_OPACITY = 0.8f;
private final float OPACITY_INCREMENT = 0.05f;
private final int FADE_REFRESH_RATE = 20;
private final int WINDOW_RADIUS = 15;
private final int CHARACTER_LENGTH_MULTIPLIER = 7;
private final int DISTANCE_FROM_PARENT_TOP = 100;
private JFrame mOwner;
private String mText;
private int mDuration;
private Color mBackgroundColor = Color.BLACK;
private Color mForegroundColor = Color.WHITE;
public Toast(JFrame owner) {
super(owner);
mOwner = owner;
}
private void createGUI() {
setLayout(new GridBagLayout());
addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
setShape(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(),
WINDOW_RADIUS, WINDOW_RADIUS));
}
});
setAlwaysOnTop(true);
setUndecorated(true);
setFocusableWindowState(false);
setModalityType(ModalityType.MODELESS);
setSize(mText.length() * CHARACTER_LENGTH_MULTIPLIER, 25);
getContentPane().setBackground(mBackgroundColor);
JLabel label = new JLabel(mText);
label.setForeground(mForegroundColor);
add(label);
}
public void fadeIn() {
final Timer timer = new Timer(FADE_REFRESH_RATE, null);
timer.setRepeats(true);
timer.addActionListener(new ActionListener() {
private float opacity = 0;
@Override
public void actionPerformed(ActionEvent e) {
opacity += OPACITY_INCREMENT;
setOpacity(Math.min(opacity, MAX_OPACITY));
if (opacity >= MAX_OPACITY) {
timer.stop();
}
}
});
setOpacity(0);
timer.start();
setLocation(getToastLocation());
setVisible(true);
}
public void fadeOut() {
final Timer timer = new Timer(FADE_REFRESH_RATE, null);
timer.setRepeats(true);
timer.addActionListener(new ActionListener() {
private float opacity = MAX_OPACITY;
@Override
public void actionPerformed(ActionEvent e) {
opacity -= OPACITY_INCREMENT;
setOpacity(Math.max(opacity, 0));
if (opacity <= 0) {
timer.stop();
setVisible(false);
dispose();
}
}
});
setOpacity(MAX_OPACITY);
timer.start();
}
private Point getToastLocation() {
System.out.println("Here!");
System.out.println(mOwner);
Point ownerLoc = mOwner.getLocation();
// !! Window win = SwingUtilities.getWindowAncestor(someComponent);
// Point ownerLoc = win.getLocation();
int x = (int) (ownerLoc.getX() + ((mOwner.getWidth() - this.getWidth()) / 2));
int y = (int) (ownerLoc.getY() + DISTANCE_FROM_PARENT_TOP);
return new Point(x, y);
}
public void setText(String text) {
mText = text;
}
public void setDuration(int duration) {
mDuration = duration;
}
@Override
public void setBackground(Color backgroundColor) {
mBackgroundColor = backgroundColor;
}
@Override
public void setForeground(Color foregroundColor) {
mForegroundColor = foregroundColor;
}
public static Toast makeText(JFrame owner, String text) {
return makeText(owner, text, LENGTH_SHORT);
}
public static Toast makeText(JFrame owner, String text, Style style) {
return makeText(owner, text, LENGTH_SHORT, style);
}
public static Toast makeText(JFrame owner, String text, int duration) {
return makeText(owner, text, duration, Style.NORMAL);
}
public static Toast makeText(JFrame owner, String text, int duration,
Style style) {
Toast toast = new Toast(owner);
toast.mText = text;
toast.mDuration = duration;
if (style == Style.SUCCESS)
toast.mBackgroundColor = SUCCESS_GREEN;
if (style == Style.ERROR)
toast.mBackgroundColor = ERROR_RED;
if (style == Style.NORMAL)
toast.mBackgroundColor = NORMAL_BLACK;
return toast;
}
public void display() {
new Thread(new Runnable() {
@Override
public void run() {
try {
createGUI();
fadeIn();
Thread.sleep(mDuration);
fadeOut();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
}
}
修改强>
一种更好的,更加线程安全的display()
方法:
public void display() {
final Timer timer = new Timer(mDuration, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
fadeOut();
}
});
timer.setRepeats(false);
createGUI();
fadeIn();
timer.start();
}