PDA

View Full Version : مشکل در دسترسی به متد در جاوا



[younes]
شنبه 09 فروردین 1393, 15:46 عصر
سلام دوستان

نمیدونم چرا ولی هر کار کردم نتونستم به متد eng.load(); دسترسی داشته باشم

لطفا کمکم کنید.


package webviewbrowser;
import java.net.*;
import java.io.*;
import javax.swing.JOptionPane;
import java.util.List;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;




public class WebViewBrowser extends Application {


@Override public void start(Stage primaryStage) throws Exception {
Pane root = new WebViewPane();
primaryStage.setScene(new Scene(root, 1024, 768));
primaryStage.show();

}




/**
* The main() method is ignored in correctly deployed JavaFX
* application. main() serves only as fallback in case the
* application can not be launched through deployment artifacts,
* e.g., in IDEs with limited FX support. NetBeans ignores main().
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}


/**
* Create a resizable WebView pane
*/
public class WebViewPane extends Pane {




public WebViewPane() {
VBox.setVgrow(this, Priority.ALWAYS);
setMaxWidth(Double.MAX_VALUE);
setMaxHeight(Double.MAX_VALUE);


WebView view = new WebView();
view.setMinSize(500, 400);
view.setPrefSize(500, 400);
eng = view.getEngine();
eng.load("http://localhost/");


sock ss=new sock();
ss.start();





Button goButton = new Button("Go");
goButton.setDefaultButton(true);
EventHandler<ActionEvent> goAction = new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {


}
};
goButton.setOnAction(goAction);
eng.locationProperty().addListener(new ChangeListener<String>() {
@Override public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {


}
});
GridPane grid = new GridPane();
grid.setVgap(5);
grid.setHgap(5);
GridPane.setConstraints(goButton,1,0);
GridPane.setConstraints(view, 0, 1, 2, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.ALWAYS);
grid.getColumnConstraints().addAll(
new ColumnConstraints(100, 100, Double.MAX_VALUE, Priority.ALWAYS, HPos.CENTER, true),
new ColumnConstraints(40, 40, 40, Priority.NEVER, HPos.CENTER, true)
);
grid.getChildren().addAll( goButton, view);
getChildren().add(grid);
}


@Override protected void layoutChildren() {
List<Node> managed = getManagedChildren();
double width = getWidth();
double height = getHeight();
double top = getInsets().getTop();
double right = getInsets().getRight();
double left = getInsets().getLeft();
double bottom = getInsets().getBottom();
for (int i = 0; i < managed.size(); i++) {
Node child = managed.get(i);
layoutInArea(child, left, top,
width - left - right, height - top - bottom,
0, Insets.EMPTY, true, true, HPos.CENTER, VPos.CENTER);
}

}


















class sock extends Thread{


public void run()
{
try{
ServerSocket servic = new ServerSocket(2121);
Socket servicServer =servic.accept();
DataInputStream is = new DataInputStream(servicServer.getInputStream());



JOptionPane.showMessageDialog(null,is.readUTF(),"Error",JOptionPane.INFORMATION_MESSAGE);







is.close();
servic.close();
sock ss=new sock();
ss.start();









}
catch(Exception e){JOptionPane.showMessageDialog(null,e,"Error",JOptionPane.INFORMATION_MESSAGE);}










}
















}
}
public static WebEngine eng;
}

[younes]
شنبه 09 فروردین 1393, 15:49 عصر
و توضیح درباره کد بالا ==> من میخوم از کلاس عمومی sock که Thread رو بسط داده به متد eng.load(); دسترسی پیدا کنم و با اون یه آدرس url رو باز کنم و تقریبا هر راهی که رفتم نتیجه نگرفتم.

vahid-p
شنبه 09 فروردین 1393, 17:11 عصر
اول اینکه خیلی برنامت خیلی بد کپی شده، تا مرتبش کردم کلی زمان برد. اما قبل از اینکه دقیق بفهمم منظورت چیه، دلیل اینکه تو متد run کلاس sock چرا دوباره از خود sock نیو کردی رو نفهمیدم؟
برای اینکه بتونی در sock از eng.load() استفاده کنی، مسلمه که تو به آبجکتش نیاز داری. برای این کار خیلی راحت یک فیلد و یک کانستراکتور برای sock درست کن که آبجکت از نوع WebEngine رو بگیره :
private WebEngine engine;
public sock(WebEngine engine){
this.engine=engine;
}
حالا تو متد run کلاس sock با استفاده از engine.load میتونی آدرس های دیگه ای رو لود کنی. اینکاری که کردی که تو متد run کلاس sock اومدی دوباره new کردی که از cpu زیاد کار میکشه و تا بخواد یه صفحه لود شه، یه صفحه دیگرو درخواست میده و... . مگر اینکه یه جوری کنترلش کنی.
من کلاس ها رو دوباره میذارم، که مرتب تر در دسترس بقیه باشه، البته تغییراتی که گفتم اعمال کردم و دو خطی که بالاتر توضیحش رو دادم در کلاس sock رو کامنت کردم :
کلاس WebViewBrower.java
package webviewbrowser;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;




public class WebViewBrowser extends Application {


@Override public void start(Stage primaryStage) throws Exception {
Pane root = new WebViewPane();
primaryStage.setScene(new Scene(root, 1024, 768));
primaryStage.show();
}




/**
* The main() method is ignored in correctly deployed JavaFX
* application. main() serves only as fallback in case the
* application can not be launched through deployment artifacts,
* e.g., in IDEs with limited FX support. NetBeans ignores main().
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}


}

کلاس WebViewPane.java
package webviewbrowser;


import java.util.List;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;

/**
* Create a resizable WebView pane
*/
public class WebViewPane extends Pane {
public static WebEngine eng;

public WebViewPane() {
VBox.setVgrow(this, Priority.ALWAYS);
setMaxWidth(Double.MAX_VALUE);
setMaxHeight(Double.MAX_VALUE);


WebView view = new WebView();
view.setMinSize(500, 400);
view.setPrefSize(500, 400);
eng = view.getEngine();
eng.load("http://www.google.com/");

sock ss=new sock(eng);
ss.start();

Button goButton = new Button("Go");
goButton.setDefaultButton(true);
EventHandler<ActionEvent> goAction = new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent event) {

}
};
goButton.setOnAction(goAction);
eng.locationProperty().addListener(new ChangeListener<String>() {
@Override public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {


}
});
GridPane grid = new GridPane();
grid.setVgap(5);
grid.setHgap(5);
GridPane.setConstraints(goButton,1,0);
GridPane.setConstraints(view, 0, 1, 2, 1, HPos.CENTER, VPos.CENTER, Priority.ALWAYS, Priority.ALWAYS);
grid.getColumnConstraints().addAll(
new ColumnConstraints(100, 100, Double.MAX_VALUE, Priority.ALWAYS, HPos.CENTER, true),
new ColumnConstraints(40, 40, 40, Priority.NEVER, HPos.CENTER, true)
);
grid.getChildren().addAll( goButton, view);
getChildren().add(grid);
}


@Override protected void layoutChildren() {
List<Node> managed = getManagedChildren();
double width = getWidth();
double height = getHeight();
double top = getInsets().getTop();
double right = getInsets().getRight();
double left = getInsets().getLeft();
double bottom = getInsets().getBottom();
for (int i = 0; i < managed.size(); i++) {
Node child = managed.get(i);
layoutInArea(child, left, top,
width - left - right, height - top - bottom,
0, Insets.EMPTY, true, true, HPos.CENTER, VPos.CENTER);
}
}
}

کلاس sock.java
package webviewbrowser;

import java.io.DataInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javafx.scene.web.WebEngine;
import javax.swing.JOptionPane;

public class sock extends Thread{
private WebEngine engine;
public sock(WebEngine engine){
this.engine=engine;
}

@Override
public void run()
{
try{
ServerSocket servic = new ServerSocket(2121);
Socket servicServer =servic.accept();
DataInputStream is = new DataInputStream(servicServer.getInputStream());
JOptionPane.showMessageDialog(null,is.readUTF(),"E rror",JOptionPane.INFORMATION_MESSAGE);
is.close();
servic.close();
// sock ss=new sock(engine);
// ss.start();
}catch(Exception e){
JOptionPane.showMessageDialog(null,e,"Error",JOptionPane.INFORMATION_MESSAGE);
}
}
}

[younes]
شنبه 09 فروردین 1393, 21:33 عصر
من این تغییرات رو تو کدم اعمال کردم ولی بازم نتیجه نداد یعنی اون متد در run کلاس sock در دسترس بود ولی هیچ آدرسی رو باز نمی کرد. در هیچ حالتی

من در واقع قصد داشتم برنامه از طریق پرت 2121 منتظر باشه و بعد از دریافت آدرس url آن رو با متد eng.load باز کنه و برای اینکه بعد از دریافت منتظر آدرس بعدی باشه دوباره کلاس sock رو new کردم ویه Thread جدید شروع کردم.

این کد های شمارو رو کامپایل کنم کارم راه میوفته؟

vahid-p
یک شنبه 10 فروردین 1393, 13:46 عصر
شما تو پست اول گفتید : "نمیدونم چرا ولی هر کار کردم نتونستم به متد eng.load(); دسترسی داشته باشم"

الان شما دسترسی دارید ولی اینکه اجرا نمیشه مسئلش یه چیز دیگست. من دقیق نفهمیدم چرا از Thread های جدید استفاده میکنید، اما اینم زیاد مسئله مهمی نیست، مسئله اصلی اینه که eng.load کار خودش رو به درستی انجام میده ولی اصلا خط دستور به اونجا نمیرسه که بخواد اجرا بشه.
برای اینکه مطمئن بشید از Debugger استفاده کنید و trace کنید خواهید دید که در دستور servic.accept() توقف میکنه. تا دستوری از یک کلاینت یا سرور دیگه ای نیاد روی این آدرس و پورت، چطور میخواهید ادامه بده؟ اگر شما کد مورد نظرش رو نوشتین برای کلاینت بعدی، خب بذارید تا ببینیم مشکل کجاست، اگر هم نه، خب باید بنویسید.
در کل بتونید صورت مسئله رو به صورت کامل بگید اصلا قراره چه کاری انجام بشه، فکر میکنم بهتر بتونیم راهنمایی کنیم.

[younes]
یک شنبه 10 فروردین 1393, 14:31 عصر
ممنون از توجه تون

برنامه کلاینت با جرا شدن یه آدرس url به localhost و پرت 2121 میفرسته و البته بدرستی این کار را انجام میده

برنامه از دو جزء کلاینت و سرور تشکیل شده که کلاینت یکسری url ها رو برای سرور میفرسته و سرور اون هارو باز میکنه و چون برنامه سرور باید غیر از گوش دادن به پورت2121 و منتظر موندن کار دیگه ای انجام بده پس منطقیه از Thrread ها استفاده کنم و بعد از این که کلاینت یه آدرس فرستاد کلاس sock باید اون رو در مرورگر باز کنه و در ظمن دوباره New کردم تا دوباره منتظر آدرس بعد باشه

این new کردن جدید غیر عادیه؟ چون من جاوا رو خود آموز یاد میگیرم شاید این کار استاندارد نباشه یا حتی اشتباه باشه اگه این طوره بگید درستش چیه؟

vahid-p
یک شنبه 10 فروردین 1393, 15:21 عصر
قبل از اینکه یادم بره، خط اول که شما ServerSocket ایجاد کردید، برای هر Thread فکر میکنم مشکل ساز میشه. چون Server یکی هست برای این پرت، اون کلاینت ها هستند که چند تا میتونند باشند که حتی میتونی محدودش رو با کانستراکتور مشخص کنی. اما فرض کنیم یک سرور و یک کلاینت باشند (اگر چند کلاینت باشه، بهتره که ServerSocket رو تو WebViewPane ایجاد کنیم و مثل اینجین برای بقیه از طریق کانستارکتور بفرستیم ).
پیشنهاد من اینه که شما بیایید و برای سرور یک Thread ایجاد کنید و داخل Thread یکبار کلاینت رو accept کنه و بعدش دیگه هر بار با Thread جدید نیاد و کلاینت رو accept کنه. بعد اون میتونی یه حلقه بذاری که اطلاعات ارسالی از طرف کلاینت رو دریافت کنه. هر آدرسی که دریافت کرد رو لود کنه. حالا اینجا دو مسئله وجود داره که در زمانی که صفحه داره لود میشه آدرس جدید اومد عوض کنه یا صبر کنه صفحه لود بشه، بعد آدرس بعدی رو بگیره. به نظرم اینجا بهتره هر دو تا رو پیاده کنی ببینی کدوم اونی هست که میخوای.
من چنین چیزی مد نظرم هست :
public class sock extends Thread{
private WebEngine engine;
private volatile boolean flag;
private String str;

public sock(WebEngine engine){
this.engine=engine;
flag=true;
}

@Override
public void run()
{
try{
ServerSocket serverSocket=new ServerSocket(2121);
Socket socket =serverSocket.accept();
Scanner cin=new Scanner(socket.getInputStream());
while(flag){
str=cin.next();
new Thread(new Runnable() {

@Override
public void run() {
engine.load(str);
}
}).start();
}
cin.close();
serverSocket.close();
}catch(Exception e){
JOptionPane.showMessageDialog(null,e,"Error",JOptionPane.INFORMATION_MESSAGE);
}
}
}

یا حلقمون این باشه :
while(flag){
str=cin.next();
engine.load(str);
}
flag هم برای کنترل هست که تا کی ارتباط برقرار باشه. یه متد Setter بذار و هر وقت خواستی با یک Button اونو false کن.
چون کلاس کلاینت رو نداشتم، نتونستم امتحان کنم، برا همین از کارکردش 100 درصد مطمئن نیستم!