Salve ragazzi, sono qui perchè ho un grosso grattacapo.
Ho creato un' applet.
Il codice HTML per la mia applet è:
<applet code=gui.clientGUI.MyApplet.class
archive="QTminer.jar"
width=400 height=200>
</applet>
e questo è il contenuto del file jar:
- C:\Users\Francesco\Desktop>jar tf QTminer.jar
META-INF/MANIFEST.MF
.project
gui/GUI$1.class
gui/GUI$2.class
gui/GUI$3.class
gui/GUI.class
gui/GUI.java
gui/clientGUI/LoginFrame$1.class
gui/clientGUI/LoginFrame$2$1.class
gui/clientGUI/LoginFrame$2.class
gui/clientGUI/LoginFrame$3$1.class
gui/clientGUI/LoginFrame$3.class
gui/clientGUI/LoginFrame$4$1.class
gui/clientGUI/LoginFrame$4.class
gui/clientGUI/LoginFrame.class
gui/clientGUI/LoginFrame.java
gui/clientGUI/ClientFrame$1.class
gui/clientGUI/ClientFrame$2$1.class
gui/clientGUI/ClientFrame$2.class
gui/clientGUI/ClientFrame$3$1$1.class
gui/clientGUI/ClientFrame$3$1.class
gui/clientGUI/ClientFrame$3.class
gui/clientGUI/ClientFrame$4$1.class
gui/clientGUI/ClientFrame$4.class
gui/clientGUI/ClientFrame$5$1.class
gui/clientGUI/ClientFrame$5.class
gui/clientGUI/ClientFrame$6$1.class
gui/clientGUI/ClientFrame$6$2.class
gui/clientGUI/ClientFrame$6.class
gui/clientGUI/ClientFrame.class
gui/clientGUI/ClientFrame.java
gui/clientGUI/MyApplet$1$1$1.class
gui/clientGUI/MyApplet$1$1$2.class
gui/clientGUI/MyApplet$1$1.class
gui/clientGUI/MyApplet$1.class
gui/clientGUI/MyApplet.class
gui/clientGUI/MyApplet.java
gui/clientGUI/SplashScreen$1.class
gui/clientGUI/SplashScreen.class
gui/clientGUI/SplashScreen.java
gui/resources/LoginFrame_background.jpg
gui/resources/QTminer_background_original.jpg
gui/resources/Qtminer_background.jpg
.classpath
prima che vi dica quale sia il problema, vi mostro alcune delle classi principali che i frame, in questa applet, estenderanno e/o sfrutteranno:
1. GUI CLASS
Questa classe è estesa da tutti i frame dell'applet (tranne quello iniziale, in cui c'è il metodo init, per intenderci).
Contiene metodi per il caricamento dei componenti grafici e degli eventi e per inserire eventi nell'EDT.
Ecco il codice della Classe GUI:
import java.awt.EventQueue;
import java.lang.reflect.InvocationTargetException;
import javax.swing.SwingUtilities;
public abstract class GUI{
private volatile boolean showable=false;
public GUI(){
if (!EventQueue.isDispatchThread()){
try {
SwingUtilities.invokeAndWait(new Runnable(){
public void run(){
synchronized(GUI.this){
initGraphics();
setEventListeners();
showable=true;
GUI.this.notify();
}
}
});
}
catch (InvocationTargetException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
synchronized(GUI.this){
initGraphics();
setEventListeners();
showable=true;
GUI.this.notify();
}
}
}
protected void scheduleGUIAction(Runnable toRun){
if (toRun!=null ){
try {
SwingUtilities.invokeAndWait(toRun);
}
catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
}
protected void scheduleAction(long delayTimeMS,Runnable toRun){
Thread T=new Thread(new Runnable(){
public void run(){
try {
if (delayTimeMS>0)Thread.sleep(delayTimeMS);
if (toRun!=null) toRun.run();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
T.start();
}
protected abstract void initGraphics();
protected abstract void setEventListeners();
public abstract void inShow();
public static void show(GUI object){
Thread T=new Thread(new Runnable(){
public void run(){
if (object.showable==false){
synchronized(object){
try {
object.wait();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
object.inShow();
}
});
T.start();
}
}
Spiegherò brevemente cosa fanno alcuni di questi metodi:
protected abstract void initGraphics();
protected abstract void setEventListeners();
public abstract void inShow();
initGraphics() - inizializza i componenti grafici nel frame.
setEventListeners() -Qui verranno raggruppati tutti gli event listeners.
inShow() - Questo metodo serve a indicare cosa deve essere fatto quando la classe GUI chiama, tramite il metodo statico show, il metodo inShow() su un oggetto GUI passato in input.
2. APPLET CLASS
Qui è dove inizia la mia applet, nessun costruttore, solo il metodo init().
import gui.GUI;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.UIManager.LookAndFeelInfo;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.lang.reflect.InvocationTargetException;
@SuppressWarnings("serial")
public class MyApplet extends JApplet{
static volatile boolean closed=true;
public void init(){
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
}
catch (Exception e) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e1) {
e1.printStackTrace();
}
}
getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
JButton btnStartApplication = new JButton("Start Application");
btnStartApplication.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
closed=false;
Thread T=new Thread(new Runnable(){
public void run(){
while (!closed){
if (btnStartApplication.isEnabled()==true){
try {
SwingUtilities.invokeAndWait(new Runnable(){
public void run(){
btnStartApplication.setEnabled(false);
SplashScreen ss=new SplashScreen();
GUI.show(ss);
}
});
}
catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
}
SwingUtilities.invokeLater(new Runnable(){
public void run(){
btnStartApplication.setEnabled(true);
}
});
}
});
T.start();
}
});
getContentPane().add(btnStartApplication);
}
}
Nulla di strano qui, notate solo come viene creato l'oggetto SplashScreen che vedremo a breve.
3. SPLASHSCREEN CLASS
import gui.GUI;
import javax.swing.JWindow;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import javax.swing.SwingConstants;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Color;
public class SplashScreen extends GUI{
private JWindow window;
private JLabel lblNewLabel;
@Override
protected void initGraphics() {
window=new JWindow();
window.setBounds(new Rectangle(0, 0, 883, 590));
window.setLocationRelativeTo(null);
window.getContentPane().setLayout(null);
lblNewLabel = new JLabel("Welcome",SwingConstants.CENTER);
lblNewLabel.setForeground(Color.DARK_GRAY);
lblNewLabel.setFont(new Font("Segoe UI", Font.BOLD | Font.ITALIC, 24));
lblNewLabel.setBounds(0, 313, 883, 41);
window.getContentPane().add(lblNewLabel);
JLabel label = new JLabel("");
label.setIcon(new ImageIcon(this.getClass().getResource("/gui/resources/Qtminer_background.jpg")));
label.setBounds(0, 0, 883, 592);
window.getContentPane().add(label);
}
@Override
protected void setEventListeners() {
}
@Override
public void inShow() {
scheduleGUIAction(new Runnable(){
public void run(){
window.setVisible(true);
}
});
scheduleAction(1500,new Runnable(){
public void run(){
ClientFrame cf=new ClientFrame();
GUI.show(cf);
window.dispose();
}
});
}
}
Un semplice SplashScreen, come vedete.
THE PROBLEM
Finalmente è ora di indicare il problema qual è:
Quando eseguo la mia applet dentro eclipse, tutto funziona, ma quando esporto in jar e la lancio tramite browser, solo la mia applet class viene "mostrata", cioè la finestra in cui c'è il bottone "Start Application". e anche se lo premo, non accade nulla.
Cosa sto sbagliando? potete aiutarmi? grazie.