Beruflich Dokumente
Kultur Dokumente
Client/Server Based Statistical Computing: Dissertation
Client/Server Based Statistical Computing: Dissertation
Client/Server Based Statistical Computing: Dissertation
DISSERTATION
zur Erlangung des akademischen Grades
doctor rerum politicarum
(dr. rer. pol.)
im Fach Statistik und Ökonometrie
eingereicht an der
Wirtschaftswissenschaftliche Fakultät
Humboldt-Universität zu Berlin
von
Herr Dipl.-Kfm. Heiko Lehmann
geboren am 26.06.1970 in Berlin
Keywords:
Client/Server Architecture, XploRe, Java, Statistical Computing, Electronic
Books, Interactive Teaching
iii
iv
Zusammenfassung
Schlagwörter:
Client/Server Architektur, XploRe, Java, Statistisches Rechnen, Elektroni-
sche Bücher, Interaktives Lehren
v
vi
Acknowledgments
vii
viii
Contents
1 Introduction 1
1.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Structure of this Thesis . . . . . . . . . . . . . . . . . . . . . . 4
2 Client/Server Computing 7
2.1 Client/Server Computing - A Closer Look . . . . . . . . . . . 8
2.1.1 Client . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.2 Server . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.3 Middleware . . . . . . . . . . . . . . . . . . . . . . . . 9
2.1.4 N-Tiered Models . . . . . . . . . . . . . . . . . . . . . 10
2.1.5 Fat Clients versus Thin Clients . . . . . . . . . . . . . 11
2.2 From Client/Server to Distributed Computing . . . . . . . . . 13
2.3 Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
2.4 Statistical Computing vs. Web Services . . . . . . . . . . . . . 18
ix
CONTENTS
4 XQC in Detail 43
4.1 XQC in Action . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.1.1 Application versus Applet . . . . . . . . . . . . . . . . 43
4.1.2 Configuration . . . . . . . . . . . . . . . . . . . . . . . 45
4.1.3 Getting Connected . . . . . . . . . . . . . . . . . . . . 46
4.1.4 Desktop . . . . . . . . . . . . . . . . . . . . . . . . . . 47
4.1.5 XploRe Quantlet Editor . . . . . . . . . . . . . . . . . 50
4.1.6 Data Editor . . . . . . . . . . . . . . . . . . . . . . . . 52
4.1.7 Method Tree . . . . . . . . . . . . . . . . . . . . . . . 58
4.1.8 Graphical Output . . . . . . . . . . . . . . . . . . . . . 62
4.1.9 Special Settings . . . . . . . . . . . . . . . . . . . . . . 65
4.1.10 Getting Help . . . . . . . . . . . . . . . . . . . . . . . 67
4.2 Programming Structure of the XQC . . . . . . . . . . . . . . . 68
4.2.1 XClient - The Starting Point . . . . . . . . . . . . . . . 69
4.2.2 User Interfaces . . . . . . . . . . . . . . . . . . . . . . 71
4.2.3 Character User Interface - CUI . . . . . . . . . . . . . 72
4.2.4 Graphical User Interface - GUI . . . . . . . . . . . . . 74
x
CONTENTS
8 Conclusions 121
xi
CONTENTS
xii
List of Figures
xiii
LIST OF FIGURES
6.1 Scatter plots with linear regression and kernel regression esti-
mate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
6.2 Reproducible research . . . . . . . . . . . . . . . . . . . . . . 102
xiv
LIST OF FIGURES
xv
LIST OF FIGURES
xvi
List of Tables
xvii
LIST OF TABLES
xviii
Chapter 1
Introduction
1.1 Motivation
1
Introduction
Of course this is just a single example. But as I learned during the last
several years - I am not the only one, who faced problems like this.
An enormous number of statistical methods have been developed during the
last three decades, e.g. nonparametric methods, bootstrapping time series,
wavelets, estimation of diffusion coefficients. To implement these new meth-
ods, the developer usually uses a programming environment he is familiar
with. Thus, such methods are only available for a certain software package,
but not for widely used, standard software packages like MS Excel. To apply
these methods to empirical analysis, a potential user may be facing any num-
ber of problems. It may even be impossible for him/her to use the methods
without rewriting them in a different programming language. Even if one
wants to apply the new method to simulated data in order to understand
the methodology, he/she is confronted with the same drawbacks. A similar
problem occurs in teaching statistics. Since students usually do not have
the same statistical software packages as their teacher, illustrating examples
have to be executable with standard tools.
In general, two kinds of statisticians are involved in the distribution process of
newly implemented methods, the provider and the user. The aim of our work
is to close the gap between them. To merge their interests, we introduce a
statistical middle ware, a software environment that provides the opportunity
to connect user and provider with reasonable effort. For this reason such an
environment should have the following features:
4. Documentation tools.
2
1.1 Motivation
3
Introduction
puting is the separation of a large piece of software into its constituent parts,
thus creating the opportunity for easier development (for our purposes, to
integrate new statistical methods) and better maintainability, to facilitate
clients and servers running on the appropriate hardware and software plat-
forms for their functions. The client/server architecture is intended to im-
prove flexibility, interoperability, usability and scalability as compared to
common software packages.
4
1.2 Structure of this Thesis
graphical user interface on the other. The realizations of special Java classes,
basically those that form the components of the XQC, are explained in detail.
In Chapter 5, we compare our Java client/server model for statistical com-
puting with other approaches, such as CGI techniques and “standalone” Java
applets. We also try to work out their advantages and disadvantages.
Chapter 6 describes an example for a practical use of our XploRe Quantlet
Client/Server architecture. Making research reproducible has become an
important issue these days. It helps readers of scientific articles to validate
presented content, and to use recently published methods within their own
work. The XploRe Quantlet Client is completely programmed using the Java
programming language. Due to this characteristic, it can easily be integrated
into HTML or PDF content. We describe types of presentations and show
how our XQC/XQS architecture can help to achieve reproducibility. The
MD*Book tool - also described in this chapter - can be used for creating
electronic documents (e-books, e-teaching documents) out of a LATEX file.
In Chapter 7 we introduce the statistical teach ware package MM*Stat. It
is a flexible and applicable tool for teaching and learning statistics in basic
studies. An important characteristic of MM*Stat is its interactive capability.
This capability enables the user to study statistical methods using different
variables or data sets, and changing the sample size or the parameters of
statistical methods. To integrate interactive capability, the XploRe Quantlet
Client/Server architecture is used. The XQC runs as a Java applet integrated
into MM*Stat’s HTML context.
In Chapter 8 we summarize our work.
5
Introduction
6
Chapter 2
Client/Server Computing
7
Client/Server Computing
Client 1
Client 2 Server
Client 3
2.1.1 Client
8
2.1 Client/Server Computing - A Closer Look
the client has to fulfill is the management of local resources like keyboard,
monitor and peripherals.
The number of clients accessing a server is not limited per model definition.
Rather, limitations are set by the technical possibilities of the server. The
client itself can offer services to other clients acting as a server to those clients.
2.1.2 Server
2.1.3 Middleware
• Media protocols,
• Transport protocols,
• Client/server protocols.
9
Client/Server Computing
the transportation of data packages from client to server and back to client
possible. The most common transport protocols are the Transmission Con-
trol Protocol / Internet Protocol (TCP/IP) and Novell’s IPX/SPX. The
client/server protocol comes into action after the physical connection is es-
tablished and the type of data transmission has been clarified. Client and
server must speak the same language in order to be able to communicate
with each other. This “same” language is defined within the middleware.
The client/server protocol specifies how a client must authenticate itself and
in which way service has to be requested. This protocol also specifies how
the server must answer client requests in order to guarantee the client un-
derstands the results.
Middleware can be grouped according to its task - e.g. to database mid-
dleware (SQL, ODBC), Groupware middleware (Microsoft Exchange, Lotus
Notes) and Internet middleware (HTTP, SSL).
10
2.1 Client/Server Computing - A Closer Look
11
Client/Server Computing
every client in the system. On the other hand, changes on the server side
are not compellingly necessary. This enables high stability and integrity of
the system. A drawback of this solution is less encapsulation of the data,
compared to a “fat server” architecture. The client takes over more logic and
more responsibility, which presupposes a deeper knowledge of the data and
the way the data are structured and organized on the server side.
Within “thin client / fat server” systems, the application logic lies on the
side of the server. Concentrating the application logic on the server side
simplifies maintenance and extensions of the system. Software updates re-
quire only an update of the appropriate server. Changes on the side of the
client are usually not necessary (depending on the kind of update). Often,
updates or adjustments can be accomplished without informing the user of
the client about the changes at all. As already mentioned before, updating
a system where the application logic lies on the client side could result in a
change or even in an exchange of every single client. This procedure can be
extremely complex and cost-intense, depending on the size of the developed
system and/or number of clients in the system. “Thin clients” are a good
choice for “task-oriented” processes. These processes are characterized by a
client whose major task consists of offering a common user interface for data
input and data output. Automatic teller machines, Web server and most
enterprise resource planning (ERP) systems are practical examples of this
kind of architecture.
12
2.2 From Client/Server to Distributed Computing
13
Client/Server Computing
server-stub-object. On the client side (the component that triggers the inter-
action), the remote-object is represented by a client-stub-object. This client-
stub-object offers the same method signatures as the remote-object. Figure
2.3 illustrates the interaction between all components.
Client-Stub-Object Server-Stub-Object
RPC-Layer RPC-Layer
The client uses the client-stub-method to create (“pack”) and send a request
to the server. The “packed” request is sent to the server-stub-object using
a defined transport protocol, like TCP/IP. The server-stub-object unpacks
the received information and calls the method on the remote object. The
transmission of results back to the client-stub takes places in a similar way
[Deg02].
The most common ORPC standards are:
14
2.2 From Client/Server to Distributed Computing
CORBA defines its own interface description language - the “Interface Defini-
tion Language” (IDL) - that works independently of other programming lan-
guages. The IDL is used to create client-stub-objects and server-stub-objects
in a required programming language (e.g. C, C++, Java) out of IDL files.
The most important part of the CORBA architecture is the “Object Request
Broker” (ORB). It defines the object model and offers bidirectional location-
transparent object access. The “Generic Inter-ORB Protocol” (GIOP) or for
TCP/IP environments “Internet Inter-ORB Protocol” (IIOP) is used as the
communication protocol [Sie00].
The fact that there are at least the three “standards” for distributed comput-
ing implies that the “Best Solution” does not exist. Each of the approaches
described above is not completely perfect in one way or the other. Their
use is limited to a more or less homogeneous environment: DCOM requires
a Microsoft environment, RMI requires a Java environment (although Java
offers runtime environments for many platforms). CORBA is available on
several platforms. However, it presupposes a high measure of adjustments of
the client’s software to the CORBA architecture.
15
Client/Server Computing
In just a little more than ten years, the Internet has evolved from an academic
rarity into a powerful tool for doing business. The World Wide Web has be-
come an instrument for exchanging data and information. At the beginning,
the Web was a static medium - Web servers provided access to static HTML
pages for client browsers that rendered them for display on the user’s screen.
With the advance of distributed computing and e-Business applications, this
model has changed to a more dynamic approach - the contents of the pages
to be displayed on the client computer are more often generated on the fly
based on the users input and the contents of the business databases [Mau01].
“Interactive Web Contents” and “Web Services” have become common terms
in these days.
Searching the Internet for a definition of the term “Web Service” leads to
dozens of different results. It has become a term that means many different
things to many different people:
• “Web services are a new breed of Web application. They are self-
contained, self-describing, modular applications that can be published,
located, and invoked across the Web. Web services perform functions,
which can be anything from simple requests to complicated business
processes.” [Tid00]
16
2.3 Web Services
The Simple Object Access Protocol (SOAP) has become a widely used stan-
dard for realizing Web Services. Similar to CORBA’s communication proto-
col IIOP, SOAP enables communication between applications that are part
of the Internet or Intranet, independently of the underlying platform the
applications are installed on. SOAP represents a Remote Procedure Call
(RPC) protocol. Up to this point, there is no difference between SOAP and
architectures like CORBA, RMI and DCOM.
But SOAP has one feature, which makes it unique when compared to other
RPC standards. It uses an XML-based syntax to wrap information before
transmission. A special interface description language - “Web Service De-
scription Language” (WSDL) - makes communication between distributed
objects possible. The “Hyper Text Transfer Protocol” (HTTP) is used as the
transport protocol. Wrapping all information into an XML file, and using
HTTP as the transport protocol, leads to one of the great advantages SOAP
offers. It enables SOAP to penetrate Firewalls via the standard-HTTP-port
80. Due to the fact that all information is packed within an XML file, it looks
to the server like a common HTML file and can thus pass the Firewall. But
this advantage is not undisputable since it also represents a safety-relevant
risk. The same standard-HTTP-port-80 method could be used to transport
information into Intranets, which is not really welcome (e.g. worms, viruses).
It seems to be only a matter of time before Firewalls will close this safety
gap by an intensified examination of port 80.
The XML format that SOAP uses for transportation represents a “double
edged sword”. The advantage of this format is, without a doubt, the simple
legibility of XML files, which simplifies handling (e.g. debugging a transmit-
ted file regarding its form). At the same time, this advantage also represents
SOAP’s largest disadvantage - it leads to a lack of performance compared to
other RPC architectures. The use of XML places a burden on the system
and requires additional memory and CPU resources, due to the requirement
to parse and transport XML files [dJ02]. In order to implement a SOAP
request, the programmer must generate an XML file, wrap the data to be
sent in this file and finally send the file to the server. The answer that ar-
rives from the server is also wrapped within an XML file. This file must be
parsed on the client side to extract the data, which again can be quite time
consuming. Due to the high overhead of information that comes along with
17
Client/Server Computing
the use of XML, data packages become bigger and transmission takes longer,
compared to other RPC approaches.
Practical “Web Service” applications can be divided into three groups
[Wai02]:
• Plug-in functionality . . .
. . . represents the simplest form of Web Service by adding third-party
functions like stock quotes and search boxes to Web pages.
Major players in this new Web Service landscape are not just common ser-
vice providers anymore. Rather, the extension of the Internet infrastructure
into enterprise has brought businesses from all types of industry into the field
of online services. “In the new always-on web service landscape, enterprises
are no longer at the end of the value chain. They are part of it, using the
shared infrastructure to automate interaction and transaction with their sup-
pliers, employees and customers.” [Wai02] Providing online functionalities,
enterprises become Application Service Providers - ASP’s [GTHM01].
18
2.4 Statistical Computing vs. Web Services
statistical tasks on data provided by the user or on sample data offered by the
program itself. Computed results will be presented to the user in different
ways - pure text, tables, and graphics.
Trying to split a statistical software package into single constituent parts
would generally lead to a user interface that represents the computational
results, the application itself - fulfilling computational tasks and a collection
of data and methods that can be accessed by the application. Hence, we
get three different layers. Installing every layer of the software package on
a hardware component, which best fits its requirements (e.g. a powerful
computer for the actual computation part), results in a classical, distributed
“Three-tier” client/server architecture (of course it takes a little bit more
than just splitting up existing applications - after all, the single parts have
to be able to communicate with each other). If the presentation layer is
realized in a manner that allows for an easy integration into World Wide
Web content, and the underlying protocols support communication via the
Internet, we are more closely approaching a Web Service architecture.
A distributed computing infrastructure of global scale seems to be an impor-
tant component of the next generation of scientific computing environment
[Tod04]. Using the advantages of a distributed computing environment can
help to achieve greater computational power, scalability and reusability of
data and methods:
• Reusability enables users to access data and methods, which can then
be distributed on different servers. Newly developed methods can be
made available to other users in a very short period of time.
19
Client/Server Computing
preceding sections in order to achieve the goals mentioned above. The goal
is to enable a user to access statistical computational power and statistical
methods with only the need for a common Java enabled Web browser.
20
Chapter 3
21
XploRe Quantlet Client/Server Model
CLIENT 1 CLIENT 2
Methods Quantlet Client Quantlet Client Methods
& Data & Data
MD*Serv
Methods
& Data
22
3.1 XploRe Quantlet Server
The XploRe Quantlet Server offers access to these methods. Because the
XQS is written in native code, it enables fast computation. Running on a
remote computer, the XQS can offer a high magnitude of computer power,
23
XploRe Quantlet Client/Server Model
which many users would not be able to access by other means. Having
access to the method- and database the XQS and the method- and database
respectively are easily expandable by new statistical methods via XploRe
programs (Quantlets), as well as native code methods, e.g. -dll and -so. The
Communication with MD*Serv is realized via standard I/O streams - the
XQS reads from the standard input and writes to the standard output.
24
3.2 Middleware MD*Serv
MD*Serv
Configuration Settings
Middleware MiddlewareOptions
ServerSocket
accept()
ServerThread
ClientHandler RequestHandler
Starting XQS
ClientToServerThread ClientToServerThread
Port1 = 4452
#Port2 =[port]
#Port3 =[port]
#
# ------ Server ---------------------------------------
# When a client ask MD*Serv to be serverd,
# MD*Serv executes the command stated below
# and connects the client to the standart I/O
# stream of the server.
#
#Server = [path|server executable] -ini [XQS config file]
Server = xqs.i686-pc-cygwin32.exe
#
# ------ Debug mode -----------------------------------
#
DEBUG = yes
# ------ Log file name --------------------------------
# The complete path and name of the logfile
#
LogFile = [xplmiddle.log]
#
25
XploRe Quantlet Client/Server Model
Immediately after the Middleware.class has read all given property informa-
tion it, attempts to bind a socket to the given specific port on the server. If
a successful connection to the port has been established, a new ServerThread
will be initiated. This thread listens to the socket and waits for requests.
As soon as a request arrives, the ServerThread determines the type and ini-
tiates further processing. If a client knows the host name of the machine
on which the server is running, and the port number to which the server is
connected, it can rendezvous with the server. In the event a client requests
a services, a new ClientHandler will be created. This class begins a new
session between the requesting client and the XploRe Quantlet Server. It
further initializes the data streams and carries out the “handshaking” pro-
cess. After successfully identifying the client via the arranged protocol, the
ClientHandler initiates the XploRe Server batch program, which is defined
in the configuration file. This process works exclusively for the request-
ing client. If the server program was able to start without any problems,
the ClientHandler creates two new threads - a ClientToServerThread and a
ServerToClientThread. The ClientToServerThread transmits data from the
client via TCP/IP to the XQS using its standard input stream. Conversely,
the ServerToClientThread transmits data read from the standard output of
the XQS to the client via TCP/IP. Since MD*Serv functions as a parallel
application, upon connecting requesting client and XploRe Quantlet Server,
it is ready for additional (client) requests. In its current version, MD*Serv
is capable of handling up to 50 clients simultaneously.
26
3.3 MD*Crypt Package
3.3.1 Structure
XQServerThread
XQSObjects
The MD*Crypt package, being set up in between the XQS (or MD*Serv
middleware respectively) and clients, mimics a server to possible front-end
clients. Figure 3.3 visualizes the structure of MD*Crypt.
27
XploRe Quantlet Client/Server Model
28
3.3 MD*Crypt Package
• public void terminate() - terminates the connection between XQS and XQC.
This method should be executed before terminating the XQC in order to
end the XploRe program on server side.
Communication from server back to client takes place via a common Java
listener interface offered by MD*Crypt’s XQSListener.class. This interface
must be implemented by the client. Each client class that has implemented
the XQSListener, and is also registered, receives the information regarding
content coming from the XploRe server and can thus process it. Implement-
ing means, the client class must define the following three methods:
• serverStatusChanged(int status),
• handleMdCryptException(XQSStatusMessage xqsstm),
• handleServerReply(XQSObject xqsobj).
serverStatusChanged(int status)
In order to keep the client informed about what is going on during processing,
MD*Crypt uses the serverStatusChanged(int status) method. At all times
during processing, if the status changes, all listeners registered will be no-
tified. This information can be used by the client to trigger certain events,
or just as information for the user of the client. The status information is
defined as follows:
• Not connected,
• Socket initialized,
• Handshake done,
29
XploRe Quantlet Client/Server Model
• Connection accepted,
• Server ready,
• Server busy,
• Server waiting.
handleMdCryptException(XQSStatusMessage xqsstm)
handleServerReply(XQSObject xqsobj)
• XQSObject
XQSObject serves as a superclass for XploRe Quantlet server objects. Every
XQSObject class is derivied from it.
Methods:
public int getType() - returns the type of this XQSObject (e.g. OUTPUT,
CREATE DISPLAY, GRAPHICS, READ VALUE, SELECT ITEM,
ADD DATA, STATUS).
30
3.3 MD*Crypt Package
• XQSOutputObject
This object represents a text output object of an XQS. The only data
contained in an object of this type is a String.
Methods:
public java.lang.String getText() - returns the text output of an XploRe
Quantlet executed on the XQS.
• XQSDisplayObject
This object represents a display object of an XQS. The only data contained
in an object of this type are the display id, the number of rows in it and
the number of columns.
Methods:
public int getId() - returns the id of this XQSDisplayObject.
public int getCols() - returns the number of columns of this XQSDisplay-
Object.
public int getRows() - returns the number of rows of this XQSDisplayObject.
• XQSGraphicsObject
This object represents a graphical object of an XQS. It holds the XQS-
DataObjects, which are meant to be shown within a display, as well as
property information about the the display itself.
Methods:
public int getCol() - returns the number of columns of this XQSGraphic-
sObject.
public java.lang.Object getDataObject(int index) - returns the index th
element of DataObjectList. That index must not become larger than the
value of ndp.
public java.util.Vector getDataObjectList() - returns the complete DataOb-
jectList hold by this XQSGraphicsObject.
public int getDim() - returns the dimension of this XQSGraphicsObject.
public int getDisplayID() - returns the ID of this XQSGraphicsObject.
public java.lang.String getName() - returns the name of this XQSGraphic-
sObject.
public int getNdp() - returns the number of data parts this XQSGraphic-
31
XploRe Quantlet Client/Server Model
• XQSDataObject
XQSDataObject holds the data and its further point representation. It
is used by the XQSGraphicsObject and provides additional methods for
reading the data and its properties.
Methods:
public int getDataType() - returns the type of the data. The value of this
return can either be 1, which stands for float data or 2, which stands for
text data.
public int getDim() - returns the dimension of the data.
public int getNumberOfRows() - returns the number of rows of this
XQSDataObject.
public double[] getXorgData() - returns the data for the x-dimension.
public double[] getYorgData() - returns the data for the y-dimension.
public double[] getZorgData() - returns the data for the z-dimension.
public double getXmax() - returns the maximum value of the x-dimensional
data.
public double getXmin() - returns the minimum value of the x-dimensional
data.
public double getYmax() - returns the maximum value of the y-dimensional
data.
public double getYmin() - returns the minimum value of the y-dimensional
data.
public double getZmax() - returns the maximum value of the z-dimensional
data.
public double getZmin() - returns the minimum value of the z-dimensional
data.
public double readXvalue(int i) - returns the x dimension value at index i.
public double readYvalue(int i) - returns the y dimension value at index i.
public double readZvalue(int i) - returns the z dimension value at index i.
public int getPointPolygon(int i) - returns the polygon which the point
at index i should be presented with. The XQS supports 14 polygons to
32
3.3 MD*Crypt Package
33
XploRe Quantlet Client/Server Model
• XQSReadValueObject
XQSReadValueObject represents an XQS “read value” dialog. It can hold
and modify data, which is determined on client side.
Methods:
public double getValue(int i) - returns the default value at index i.
public double[] getValueArray() - returns an array of default values.
public java.lang.String getTextValue(int i) - returns the text value at index
i.
public java.lang.String[] getTextValueArray() - returns an array of text
values.
public void setValue(int i, double newValue) - modifies the value at index i
34
3.3 MD*Crypt Package
to newValue.
public void setValueArray(double[] newValue) - modifies the values to the
content of the array newValue.
public void setTextValue(int i, java.lang.String newValue) - modifies the
text value at index i to newValue.
public void setTextValueArray(java.lang.String[] newValue) - modifies the
text values to the content of the array newValue.
• XQSSelectItemObject
XQSSelectItemObject represents an XQS “select item” dialog. In this
object, the item names are converted to a ListObject rather than an array
to make use of the additional properties and services of ListObjects.
Methods:
public java.awt.List getNamelist() - returns the list with values to be shown.
• XQSSetGOptObject
This class holds properties that are set in the setgopt(. . . ) command of
XploRe. Refer to the setgopt() help pages of XploRe to find out what the
options mean.
Methods:
public int getId() - returns the ID of this XQSSetGOptObject (equals the
ID of a plot).
public boolean getIsXaxis() - returns true if the X-axis shall be painted.
public boolean getIsYaxis() - returns true if the Y-axis shall be painted.
public boolean getIsZaxis() - returns true if the Z-axis shall be painted.
public java.lang.String getTitle() - returns the title to be printed in a plot.
public java.lang.String getXLabel() - returns the X-axis label to be printed
in a plot.
public java.lang.String getYLabel() - returns the Y-axis label to be printed
in a plot.
public int getDisplaysizex() - returns the value of horizontal display size.
public int getDisplaysizey() - returns the value of vertical display size.
35
XploRe Quantlet Client/Server Model
• XQCDoubleVector
XQCDoubleVector enables the client to store numeric arrays of dimension
one to use it with the XploRe Quantlet Server.
Constructors:
public XQCDoubleVector(double[] array, java.lang.String Name) - con-
structs a XQCDoubleVector from the given vector of elements and with a
defined name.
Methods:
public int getRows() - returns the number of rows of the vector.
public double getElement(int i) - returns element i of the vector.
public double[] getElements() - returns a vector of elements.
public void setElements(double[] elements) throws java.lang.Exception - sets
the elements of this XQCDoubleVector object.
• XQCDoubleMatrix
XQCDoubleMatrix enables the client to store numeric arrays of dimension
“two” to use it with the XploRe Quantlet Server.
Constructors:
public XQCDoubleMatrix(double[][] array, java.lang.String Name) - con-
structs a two dimensional matrix from the given matrix of elements and
with a defined name.
Methods:
public int getCols() - returns the number of columns of the matrix.
public int getRows() - returns the number of rows of the matrix.
public double getElement(int i, int j) - returns element i, j of the of the
matrix.
public double[][] getElements() - returns the matrix elements of the XQC-
DoubleMatrix object.
36
3.3 MD*Crypt Package
• XQCDoubleArray
XQCDoubleArray enables the client to store numeric arrays up to eight
dimensions to use it with the XploRe Quantlet Server.
Constructors:
protected XQCDoubleArray(double[][][][][][][][] array, java.lang.String name)
throws java.lang.Exception - constructs an array from the given array of
elements and with a defined name.
Methods:
public int[] getDimensions() - returns the dimension of the array.
public double getElement(int[] d) throws java.lang.Exception - returns the
element at array position[d[0]][d[1]][d[2]][d[3]][d[4]][d[5]][d[6]][d[7] ].
To pass and receive these data sets to and from the server, the XQServer.class
offers corresponding methods:
37
XploRe Quantlet Client/Server Model
The information given within the previous sections allow for realization of a
simple client that is able to contact the XploRe server, send XploRe com-
mands and receive and show output in the Java console.
38
3.3 MD*Crypt Package
360
370 // receives results from server
380 public XQSObject handleServerReply(XQSObject xqsobj) {
390 if (xqsobj.getType() == XQSObject.OUTPUT) {
400 XQSOutputObject xout = (XQSOutputObject) xqsobj;
410 System.out.println(xout.getText());
420 }
430 return xqsobj;
440 }
450
460 // receives the actual server status
470 public void serverStatusChanged(int i) {
480 }
490
500 // receives information about exceptions that have occurred
510 public void handleMdCryptException(XQSStatusMessage xqsSTM){
520 }
530
540 }
Running the Java program above leads to the following output on the Java
console:
Contents of _tmp
[1,] 2
First of all our test client must import the MD*Crypt package (010) to
be able to use its services. By implementing the XQSListener (030),
the client is also forced to have the three methods handleServerRe-
ply(), serverStatusChanged() and handleMdCryptException() implemented
(380, 470, 510). This enables communication from the server back to the
client. The main method (330) creates a new instance of the Client.class
- actually starting the program. The first step the program completes is
39
XploRe Quantlet Client/Server Model
The XploRe Quantlet Client (XQC) represents the front end - the user in-
terface (UI) of the XQC/XQS architecture [KL01]. The XQC is fully pro-
grammed in Java. Using a pure Java solution, the XQC does not depend on
a certain computer platform. It can run on Windows and Mac platforms, as
well as on Unix and Linux machines. Utilizing an application or a certified
applet, the XQC can access the resources of the computer on which it is
running. Because of Java’s sandbox principle, the XQC passes underlying
restrictions for accessing the local system while running as an applet. Un-
fortunately, these restrictions also inhibit its functionality of accessing local
methods and data. Figure 3.4 shows a screen shot of the XQC running as an
application.
The appearance of the XQC is based on the MS Windows XploRe version
[HKM99] to ensure easy utilization and a familiar look. In comparison to
the MS Windows version that only offers a CUI, the XQC combines a CUI
with GUI functionality. The CUI (Character User Interface) functionality
40
3.4 XploRe Quantlet Client
Property files allow for customizing the XQC to meet special needs and also
to manage its appearance and behavior. Because of its pure Java implemen-
tation, the resulting platform independence and the ability for customization
via property files, the XQC recommends itself for the integration into HTML
and PDF contents (e.g. electronic books) for visualizing statistical and math-
41
XploRe Quantlet Client/Server Model
ematical coherences.
42
Chapter 4
XQC in Detail
The following chapter will give a detailed description of the XQC’s function-
ality, as well as its internal structure.
The XploRe Quantlet Client can be initiated in two different ways. The way
depends on whether the XQC is supposed to run as a standalone application
or as an applet embedded within an HTML page. The XQC comes packed
in a single Java Archive (JAR) file, which allows easy usage. This JAR file
allows for running the XQC as an application, as well as running it as an
applet.
Running the XQC as an application does not require any programming
skills. Provided that a Java Runtime Environment (JRE) is installed on the
computer on which the XQC is executed, the xqc.jar will automatically be
recognized as an executable JAR file that opens with the program javaw (see
figure 4.1).
The XQC in this instance can be started by simply double clicking on the
xqc.jar file. The configuration file xqc.ini is optional. As described in pre-
vious sections, this file contains information about server and port number.
If the XQC initiates without being able to access this configuration file, it
43
XQC in Detail
starts with a default setup, asking for a manual input of server and port
information.
The source code to start the XQC as an applet depends on the browser
used to display the page. Figure 4.3 shows the source code for integrating
the client into an HTML page that can be used with Microsoft’s Internet
Explorer, as well as Netscape’s Navigator.
In both cases, the archive and the class that contains the main method must
be stated. The XApplet.class works as the main class for starting the XQC
as a Java applet.
44
4.1 XQC in Action
4.1.2 Configuration
Property files allow for configuring the XQC to meet the special needs of the
user. These files can be used to manage the appearance and behavior of the
XQC. As ordinary ASCII files, any text editor can alter the configuration
files. Generally, the use of all information is optional. In its actual version,
the XQC works with three different configuration files:
• xqc.ini,
• xqc language.ini,
• xqc methodtree.ini.
The file xqc.ini contains important information about the basic setup of the
XploRe Quantlet Client, such as server and port information the client is
supposed to connect to:
Server = localhost
Port = 4451
45
XQC in Detail
Size = 0.9
Width = 800
Height = 600
It also contains information about the size of the client. This information
can be maintained either relative to the actual size of the screen by using a
factor or by stating its exact width and height. If this information is missing,
the XQC begins by using its default values.
The file xqc language.ini allows for setting up the XQC’s language. This file
contains all texts used within the XQC. To localize the client, the texts have
to be translated. If no language file can be found, the client starts with its
default setup, showing all menus and messages in English.
XQCA001 = Version
XQCA002 = Not able to connect?!
XQCA003 = NoName
XQCA004 = Editor
XQCA005 = Data
XQCA006 = Connect
...
The following section describes the XQC’s functionalities, assuming that the
client is running as an application or a certified applet. This is the only
instance when the user is able to take advantage of the entire extent of
functions the XQC offers.
After starting the XQC, the client attempts to access and read information
from the configuration files. If no configuration file can be found, error
messages will pop up. These messages are meant to draw the users attention
to the fact that the file is missing or corrupted.
46
4.1 XQC in Action
If the XQC is able to access the server and port information from the con-
figuration file, it uses this information and connects to the corresponding
server. If this information cannot be found, a popup appears and enables
the manual input of server and port number (see figure 4.4).
Figure 4.5 shows a screen shot of the XQC after it has been initiated and
connected to an XploRe server. A traffic light in the lower right corner of
the screen indicates the actual status of the server. A green light means
the client has successfully connected to the server and the server is ready to
work. If the server is busy, computing previously received XploRe code, the
traffic light will be set to yellow. A red light indicates that the XQC is not
connected to the server.
4.1.4 Desktop
If no further restrictions or features are set in the configuration file (e.g. not
showing any window or starting with executing a certain XploRe Quantlet
- see Section 4.1.9) the XQC should look as shown in the screen shot. It
opens with the two screen components Console and Output Window. The
Console (figure 4.6) allows for the sending of single-line XploRe commands
to the server to be executed immediately. It also offers a history of the last
20 commands sent to the server. To repeat a command from the history, all
that is required is a mouse click on the command, and it will be copied to
the command line. Pressing the ‘Return’ key on the keyboard executes the
XploRe command.
Text output coming from the XploRe server will be shown in the Output
Window (figure 4.7). For our example, executed in the Console, a three-
47
XQC in Detail
48
4.1 XQC in Action
Output Window.
The right part of the status line at the bottom of the XQC screen, per default
shows the slogan “XploRe - The Interactive Computing Environment”. If it
has been setup in the configuration file (ShowStatusMessages = yes), at
this point status messages coming from MD*Crypt protocol and the server
itself, will also be visible. While running XploRe Quantlets, this line also
indicates the Quantlet, the server is currently working through.
At the top of the screen the XQC offers additional functions via a menu bar.
These functions are grouped into four categories:
• XQC,
• Program,
• Data,
• Help.
49
XQC in Detail
The XQC menu (see figure 4.8) contains the features Connect, Disconnect,
Reconnect and Quit.
Depending on the actual server status, not every feature is enabled. If the
client is not connected (the server status is indicated by a red traffic light),
it does not make sense to disconnect or reconnect. If the client is already
connected (server status equals a green light), the connect feature is disabled.
All four features behave as the names imply. Disconnect disconnects client
and server and closes the XploRe server process. Reconnect disconnects from
the server and sets up a new connection. Quit disconnects client and server,
closes the XploRe server process, and quits the XploRe Quantlet Client. The
Connect feature brings up a popup as shown in figure 4.4 and enables the
user to connect to a certain server and port number.
The Program menu (see figure 4.9) contains the features New Program,
Open Program (local). . . and Open Program (net). . . .
50
4.1 XQC in Action
New Program opens a new and empty text Editor Window. This window
enables the user to write complete XploRe Quantlets.
The feature Open Program (local) offers the possibility of accessing XploRe
Quantlets stored on the local hard disk drive. It is only available if the XQC
is running as an application or a certified applet. Due to the Java sandbox
restrictions, running the XQC as an unsigned applet, it is not possible to
access local XploRe Quantlets.
If the user has access to the Internet the menu item Open Program (net) can
be useful. This feature allows the opening of Quantlets that are stored on
a remote Web server. All it needs is the filename and the URL address at
which the file is located.
Figure 4.10 shows a screen shot of the Editor Window containing a simple
XploRe Quantlet.
Two icons offer actions on the XploRe code:
51
XQC in Detail
matted to a certain color, shape and size using the command setmaskp. The
result is finally shown in a single Display.
The Data menu (see figure 4.11) contains the features New Data. . . , Open
Data (local). . . , Open Data (net). . . , Download DataSet from Server. . . and
DataSets uploaded to Server.
New Data can be used to generate a new and empty Data Window. As
shown later on in this section, the Data Window does not have to be just
a simple data editor, but can also be configured to be used as a combined
Method/Data Window. Before the Data Window opens, a pop-up win-
dow as shown in figure 4.12 appears, asking for the planned dimensions -
the number of rows and columns - of the new data set. The XQC requires
this information to create the spreadsheet. This definition does not have to
be the exact and final decision, as it is possible to add and delete rows and
columns later on.
The menu item Open Data (local) enables the user to open data sets stored
on the local hard disk. Again, access to local the resources of the user’s
computer is only possible if the XQC is running as an application or a certified
applet. The file will be interpreted as a common text format file. Line breaks
within the file are considered as new rows for the data set. To recognize data
belonging to a certain column, the single data in one line must be separated
by either using a “;” or a “tab” (separating the data by only a “space” will
force the XQC to open the complete line in just on cell).
52
4.1 XQC in Action
Open Data (net) lets the user open a data set that is stored on a Web server
by specifying the URL address.
The menu item Download DataSet from Server offers the possibility of down-
loading data from the server. The data will automatically be opened in a
new Method/Data Window, offering all its features to the downloaded
data (e.g. applying methods, saving, . . . ).
The appearance of the Data Window depends on the settings in the con-
figuration file. If a Method Tree is defined and supposed to be shown, the
window shows the Method Tree on the left part and data spreadsheet on
the right part of the frame. If no Method Tree has been defined, only the
spreadsheet will be shown. The Method Tree will be discussed in more
detail in section 4.1.7. Figure 4.13 shows a screen shot of the combined
Method/Data Window.
Icons on the upper part of the Method/Data Window offer additional
functionalities:
• - saves the data to the user’s local computer (this is not possible
if running the XQC as an unsigned applet).
53
XQC in Detail
• Copy,
• Paste,
54
4.1 XQC in Action
Most of the context menu items are self-explaining. However, there are two
items that are worth taking a closer look at - ‘Set row as header line’ and
‘Set column header’. The spreadsheet has the capability to specify a header
for each column. This information can be used within XploRe Quantlets
to name the axis within a plot, making it easier for the user to interpret
graphics. A more detailed description is included in section 4.1.7. Default
values for the headers are COL1, COL2, . . . as shown in figure 4.14. Naming
a single column can be performed using the menu item ‘Set column Header’.
The name has to be maintained within the pop up window that appears
immediately upon choosing this menu item. It can also be used to change
existing column headers. The spreadsheet also has the capability for setting
column headers all at once. If the data set already contains a row with header
information - either coming from manual input or as part of an opened data
set - this row can be set as header using the menu item ‘Set Row as Header
Line’. The row with the cell that is active at that time will be cut out of the
data set and pasted into the header line.
Setting the header is also possible while opening a data set. After choosing
the data, a pop up asks whether or not the first row of the data set to
be opened should be used as the header. Nevertheless, the context menu
features described above are of course still available, enabling the user to set
or change headers afterwards.
Working with the XQC’s Method/Data Window does not necessitate any
XploRe programming knowledge. All it requires is a pointing device like the
mouse. Applying, for example, the scatter-plot-method on the two columns
would require only the following three steps:
55
XQC in Detail
The result will be a plot as shown in figure 4.14. As stated above, the selected
area can also be uploaded to the server using the icon to be analyzed
for further investigation. Figure 4.15 shows the window that pops up asking
for a name for storing the data at the server.
This new variable can be used within XploRe Quantlets, written using the
Editor Window or manipulated via the Console (figure 4.16).
All actions performed via Method/Data Window and Console will be
recorded by the XQC. This History can be accessed via the menu item
56
4.1 XQC in Action
The window also contains information that the data has been changed using
the Console:
Last but not least, it also contains the actual content of the object - in our
case the doubled value of each element of the originally uploaded data set.
The icons offered by the History Window allow for adjustments to the
history information according to the users needs:
57
XQC in Detail
58
4.1 XQC in Action
levels. In the actual version of the XQC (version 1.4) the number of levels
is limited to four levels. Children represent statistical methods that can be
used on the data. Nodes can be used to group methods.
Setting up the Method Tree does not require any Java programming skills.
All it needs is the maintenance of two configuration files. This feature makes
it possible to configure the XQC for different statistical or mathematical
purposes, e.g. ‘Basic Statistics’ or ‘Multivariate Statistics’. The executable
methods are XploRe programs (Quantlets) that can either be stored at client
side or at server side. As a defined strategy, the XQC first tries to find a
method on the client’s computer. Upon failure, the XQC looks for the method
on the server’s method pool.
Settings maintained within the xqc.ini file communicate to the XQC whether
there will be a Method Tree to be shown, and from where to get the tree
information. The client also needs to know where the methods are stored.
The MethodPath contains this information. Path statements can be either
absolute statements, or relative to the directory in which the XQC has been
initiated. For relative path information, the path must start with XQCROOT.
The settings in the example below tell the client to generate a Method Tree
by using the file xqc methodtree.ini with the XploRe Quantlets stored in the
relative subdirectory xqc_quantlets/.
ShowMethodTree = yes
MethodTreeIniFile = xqc_methodtree.ini
MethodPath = XQCROOT/xqc_quantlets/
The user of XQC is not limited to the use of just one Method Tree. Instead,
it is possible to integrate up to 50 Method Trees within one XploRe session,
using the following additional parameters:
MethodTreeIniFile2 = second_xqc_methodtree.ini
MethodTreeIniFile3 = third_xqc_methodtree.ini
...
59
XQC in Detail
The name of the method has to be identical to the name of the XploRe
program (Quantlet). The Quantlet itself has to have a procedure with the
same name as the method. This procedure is called by the XQC on execution
within the Method Tree.
The following example shows how to set up a simple Method Tree:
First of all, we define an XploRe Quantlet that we want to be part of the
Method Tree. The aim of the Quantlet should be to generate a box plot
from the selected data of the data spreadsheet. As shown in figure 4.18,
the library ‘graphic’ is loaded to make use of XploRe’s graphical features. A
procedure is needed to be executed by the XQC. The name of the procedure -
in our case ‘BoxPlot’ - has to equal the name of the saved file. The procedure
must further have two parameters:
• data - Used for passing the selected data to the XploRe Quantlet.
• names - Contains the names of the selected columns taken from the
header of the spreadsheet.
60
4.1 XQC in Action
The XploRe coding within the procedure statement is not subject to any
needs or restrictions. We read the number of selected columns (4) and create
a Display in which the number of plots depends on the number of selected
data columns (5). Within a loop, we create the box plot by using XploRe’s
‘grbox’ method (7) and show the result in the generated Display (8). Using
XploRe’s ‘setgopt’ statement (9) allows for setting up the title and labels.
Here we can use the column header passed from the spreadsheet, setting it
as the plot title.
Once we have programmed the Quantlet it needs to be integrated into a
Method Tree. For this purpose we define our own configuration file - sam-
ple tree.ini - with the following content shown in figure 4.19.
We create a node calling it ‘First Node’. Below this first node we set up
our box plot - ‘BoxPlot’ represents the XploRe Quantlet and the procedure
we have just programmed, ‘Our Box Plot’ represents the text we would like
to be shown in the Method Tree.
Now that we have programmed the XploRe Quantlet and set up the Method
Tree we still need to tell the XQC to show our Method Tree upon opening
data sets.
1 ...
2
3 ShowMethodTree = yes
4 M et ho d Tr e eI ni F il e = sample_tree . ini
5 MethodPath = XQCROOT / xqc_quantlets /
6
7 ...
The settings as shown in figure 4.20 tell the XQC to show the Method Tree
that is set up in our sample tree.ini file and to use our XploRe Quantlet stored
in a subdirectory of the XQC itself.
Now our Method Tree is ready for finally being tested. Figure 4.21 shows
a screen shot of the result of the programming and the settings made above.
61
XQC in Detail
62
4.1 XQC in Action
The scatter plot implies that there exist two clusters - genuine and counter-
feits, although some bank notes are overlapping when only the characteristics
‘lower inner frame’ and ‘diagonal’ are considered. For a more detailed inspec-
tion, three-dimensional plots can be rotated by using a pointing device such
as a mouse (with the left mouse-button pressed) or by using the keyboard’s
arrow-keys. Figure 4.23 shows the same plot as before - it has just been ro-
tated by some degrees. Now, also considering the characteristic ‘upper inner
frame’, the clusters of the data are even easier to identify. However, there
still is one data point (represented by a blue circle) that lies among the data
of the other cluster (represented by red stars). For further research, it would
be helpful to know which data point it is. Of course the user could com-
pare the characteristics of all data points to find the one. Here the XQC’s
Display offers a feature to show the point’s coordinates. This feature can
be accessed via the Display’s context menu. ‘Showing coordinates’ is not
the only option. The user could also switch between the three dimensions -
‘Show X˜Y’, ‘Show X˜Z’ and ‘Show Y˜Z’.
After the ‘Showing coordinates’ option has been chosen, all that is required
to get the information is to point the mouse arrow on a certain data point.
Figure 4.23 shows the details ‘1/70 [8.0, 11.2, 139.6]’ for the data point
that seems to be part of the ‘wrong’ cluster. ‘1/70’ implies that we deal with
data point number 70 of the first data set printed within the Display. The
information ‘first’ is important since there could be more than just one data
63
XQC in Detail
set shown in the Display. The numbers within the brackets ‘[...]’ are the
actual characteristics of that data point.
64
4.1 XQC in Action
The configuration file xqc.ini offers some more options than just storing server
and client size information. Different property statements can be used to
influence the appearance and behavior of the XploRe Quantlet Client.
ExecuteCommands = normal(10,2)
ExecuteProgram = file:///C:/.../normal.xpl
OpenInEditor = file:///C:/.../regression.xpl
OpenData = XQCROOT/decathlon.dat
DataSetWithHeader = yes (default = no)
65
XQC in Detail
The XploRe Quantlet Client can not only be started by opening an XploRe
Quantlet, but also by opening a certain data set in the Method/Data Win-
dow. For this purpose, the feature ‘OpenData’ can be used. As described in
the previous sections, the Method/Data Window offers the possibility of
maintaining column header for graphical output. If the data set contains a
header, the feature ‘DataSetWithHeader = yes’ automatically sets the first
line of the data set as the header line. Default setting for this feature is
‘DataSetWithHeader = no’. In this case, the first line will not be used as
the header line.
If Output Window and Console are not needed - the following configura-
tion settings can be used to switch them off:
All the settings described above belong to what we call the “Golden Solu-
tion”. Using these settings, it is possible to influence each component of
the XploRe Quantlet Client. This allows for embedding of the XQC into
multimedia contents for different purposes, controlling its behavior via the
configuration settings. It can be started by executing a certain Quantlet
stated in the file without displaying Console or Output Window. In this
case the XQC behaves like a Java applet programmed for a particular task.
It can also be started by opening a data set with certain predefined and
customized methods to execute the methods on the data set.
Starting the XQC by performing one of the specific actions described above
causes the client to run in a mode with limited functionalities. In this mode,
it is only possible to work with the initiated XploRe Quantlet, edit and
execute the opened Quantlet, or execute predefined methods on the opened
data set. Per default it is not possible to open new programs or data. In
most of these cases the XQC is supposed to work only for the predefined
purposes. This limitation is inherent in the “Golden Solution” definition in
order to not confuse the user with any functional overhead. To avoid this
limitation, the “Golden Solution” mode can be switched off by using the
following statement:
66
4.1 XQC in Action
The possibility of configuring the XploRe Quantlet Client for special pur-
poses, as well as its platform independence, are features that recommend
themselves for the integration into HTML and PDF contents for visualizing
statistical and mathematical coherences - [RMZ00, Kli01]. Sections 6 and
7 contain examples that illustrate how the XQC can be used for different
results.
The XQC’s Help menu contains the two menu items Online Help
and About . . . The Online Help menu item offers direct access to
the XploRe APSS - Auto Pilot Support System (http://www.xplore-
stat.de/help/ Xpl Start.html), provided that an Internet access is available.
67
XQC in Detail
The second menu item - About . . . - opens a window that contains infor-
mation about the client/server architecture currently being used, as well as
information about the Java Runtime Environment (JRE) in which the XQC
is running.
Figure 4.27 shows the general structure of the XQC and its main components.
Each square implies a single Java class. Besides the classes shown in this
figure, there also exist, what we would call, “helper classes”, which are used
by other classes within the process. Examples of these “helper classes” are:
a dialog class for message and error dialogs and classes to handle access to
local files and Internet files (data and methods). The Appendix (B) contains
the Java source code of selected XQC classes.
68
4.2 Programming Structure of the XQC
XApplet
XQServer
XClient MD*Crypt
XQSListener
XClientAction
XProperties xqc.ini
XConsole
XQSListener
XEditorFrame
XQSListener
XOutputFrame
XDisplayFrame
capsulated for non-XQC use
XDataMethodFrame
XReadValue
xqc_methodtree.ini
XSelectItem
XServerObjectList
The XClient.class (see appendix B.1) works as the “Starting Point” or “Main
Class” of the XQC. Its main-method creates a new instance of the XClient.
The Desktop Window with its menu bar represents this object visually.
The first activity the XClient-object performs is creating an instance of the
69
XQC in Detail
• serverStatusChanged(int status),
• handleMdCryptException(XQSStatusMessage xqsstm),
• handleServerReply(XQSObject xqsobj).
70
4.2 Programming Structure of the XQC
71
XQC in Detail
Most of today’s computer applications interact with the user via Graphical
User Interface, although the Character User Interface is still a widely used
tool for experienced computer users, especially for those working in the Unix
world.
The XQC’s CUI is primarily meant for experienced XploRe users. It requires
the user to be familiar with the XploRe programming language.
CONSOLE
The XQC’s component Console (see appendix B.5) represents one part of
the architecture’s Character User Interface (CUI). It consists of a command
line window that allows the entering of single-line commands which can be
sent to the server for direct processing. The Console itself does not have
an XQSListener implemented and consequently does not receive any results
coming from the XploRe Quantlet server. A history of the last 20 com-
mands sent to the server helps to keep an overview of what has been sent
to the server. They can easily be selected and executed again. Taking a
closer look at Java code - the Console is realized within the XConsole.class
extending a javax.swing.JInternalFrame. The frame itself holds two compo-
nents - a javax.swing.JTextField that represents the single command line and
javax.swing.JList that holds the list of executed commands.
To be able to react to user actions, the XConsole.class
implements the java.awt.event.KeyListener, as well as the
javax.swing.event.ListSelectionListener. The XQServer object that has
72
4.2 Programming Structure of the XQC
EDITOR
73
XQC in Detail
...
}
GUI is primarily thought of as being for users that are not familiar with the
statistical programming language XploRe and/or users that want to apply
existing statistical methods on their own data sets. The basic feature of a
GUI is a surface that can be controlled intuitively. A simple mouse-click can
trigger functions of the underlying program without the need for the user to
type a single line of code.
DESKTOP WINDOW
74
4.2 Programming Structure of the XQC
METHOD/DATA WINDOW
The most important GUI component for communication with the XploRe
server is the combined Method/Data Window. As shown in figure 4.30
this component is realized by the classes:
• XDataMethodFrame.class,
• XDataMethodAction.class,
• XDataTableModel.class,
• XDataMethodFrameTree.class.
75
XQC in Detail
76
4.2 Programming Structure of the XQC
Tree functionality of the XQC. The basis for building a tree is a data model
that contains the information regarding nodes and children, which are part of
the tree. This information is provided by the XDataMethodFrameTree.class
(see appendix B.11). The name of the file that contains information regarding
the set up of the Method Tree is passed to this class. The XDataMethod-
FrameTree.class itself extends a Java’s Properties class. This is necessary in
order to read the tree information from the configuration file. In its current
version (1.4.005) the XQC can handle up to four levels (including node and
child levels). As shown in section 4.1.7, the definition of the Method Tree
looks as follows:
77
XQC in Detail
78
4.2 Programming Structure of the XQC
1 ...
2 // begin - m e t h o d T r e e
3 // first level
4 int a = 1;
5 do {
6 nodeName [0] = getProperty ( " Node_ " + String . valueOf ( a ) , " " ) ;
7 childName [0] = getProperty ( " Child_ " + String . valueOf ( a ) , " " ) ;
8
9 if (! nodeName [0]. equals ( " " ) ) {
10 node [0] = new D e f a u l t M u t a b l e T r e e N o d e ( nodeName [0]) ;
11 root . add ( node [0]) ;
12 }
13 if (! childName [0]. equals ( " " ) ) {
14 m et h od De s cr ip t io n = c h i l d M e t h o d D e s c r i p t i o n ( childName [0]) ;
15 child [0] = new D e f a u l t M u t a b l e T r e e N o d e ( m e t h o d D e s c r i p t i o n [0]) ;
16 root . add ( child [0]) ;
17 // array - to match the path and d e s c r i p t i o n with the method
18 noOfChildren [ j ][0] = " [ " + root . toString () + " , " +
19 m et ho d De s cr ip t io n [0] + " ] " ;
20 noOfChildren [ j ][1] = m et h od D e s c r i p t i o n [1];
21 j = j + 1;
22 }
23 // second level
24 int b = 1;
25 do {
26 nodeName [1] = getProperty ( " Node_ " + String . valueOf ( a ) + " . " +
27 String . valueOf ( b ) , " " ) ;
28 childName [1] = getProperty ( " Child_ " + String . valueOf ( a ) + " . " +
29 String . valueOf ( b ) , " " ) ;
30 if (! nodeName [1]. equals ( " " ) ) {
31 node [1] = new D e f a u l t M u t a b l e T r e e N o d e ( nodeName [1]) ;
32 node [0]. add ( node [1]) ;
33 }
34 if (! childName [1]. equals ( " " ) && ! nodeName [0]. equals ( " " ) ) {
35 m et ho d De s cr ip t io n = c h i l d M e t h o d D e s c r i p t i o n ( childName [1]) ;
36 child [1] = new D e f a u l t M u t a b l e T r e e N o d e ( m e t h o d D e s c r i p t i o n [0]) ;
37 node [0]. add ( child [1]) ;
38 // array - to match the path and d e s c r i p t i o n with the method
39 noOfChildren [ j ][0] = " [ " + root . toString () + " , " + nodeName [0] +
40 " , " + m et ho d De sc r ip t i o n [0] + " ] " ;
41 noOfChildren [ j ][1] = m e th o d D e s c r i p t i o n [1];
42 j = j + 1;
43 }
44
45 ... // third and fourth level
46
47 }
48 while (! nodeName [1]. equals ( " " ) || ! childName [1]. equals ( " " ) ) ;
49 // end second level
50 a = a + 1;
51 }
52 while (! nodeName [0]. equals ( " " ) || ! childName [0]. equals ( " " ) ) ;
53 // end first level
54 // end - m e t h o d T r e e
55 ...
• The complete content of the XploRe Quantlet that stands behind “Our
Box Plot” - the XploRe code shown in figure 4.18.
79
XQC in Detail
• The XploRe procedure call, containing the data and column names as
parameters - BoxPlot(data[,1], "100 m")
The first part initiates the execution of the XploRe code at the server. Now,
because the server knows the contained procedure it can be called with our
selected data. Result is an XploRe Display as shown in figure 4.21.
DISPLAY
Output within the GUI is realized throughout the Plot Classes. These
classes are responsible for presenting server results graphically. In order
to receive results from the server, the Plot Classes have implemented
MD*Crypt’s XQSListener interface. The Plot Classes consist of four dif-
ferent main components:
• XDisplayFrame.class,
• XDisplay.class,
– XSetGOpt.class,
• XPlot.class,
– Axis.class,
– HAxis.class,
– VAxis.class,
• XPlotAction.class.
The phrase “Form Follows Function” absolutely fits those four main com-
ponents. The XDisplayFrame.class utilizes a desktop frame that works as
a container for the actual Display. The Display is realized by the XDis-
play.class. Every XploRe Display contains one or more plots. Each plot
is realized by a separate instance of the XPlot.class. All actions carried out
within a Display are handled by the XPlotAction.class. Besides those four
main components, a few other classes implement additional logic used within
the plot classes. The XSetGOpt.class handles XploRe’s “setgopt” command.
80
4.2 Programming Structure of the XQC
This class allows for setting titles and labels of plot, or the size of a Dis-
play. Three axis classes (Axis.class, HAxis.class, VAxis) are responsible for
drawing horizontal and vertical axis within two dimensional plots.
How do the four main components work together?
If the XQC’s main class - XClient.class - receives server results of type ‘CRE-
ATE DISPLAY’, it creates a new instance of the XDisplayFrame.class (see
appendix B.12). It also passes over information about Display ID and num-
ber of plots that are to be part of the Display. The aim of the XDis-
playFrame.class is to build a window that will be shown on the XQC’s desk-
top, and to call a new instance of the XDisplay.class. Both classes could
actually have been realized within one single class. The reason for using
two classes is an encapsulation of the ‘pure’ Plot Classes (XDisplay.class,
XPlot.class, XPlotAction.class). This encapsulation makes it possible to use
its functionalities outside the XQC, by integrating the Plot Classes within
other (3rd party) clients that would like to access the XploRe server [Mor04].
An example of how the ‘plot classes’ can be integrated into other clients that
want to access the XploRe server is also part of the appendix (see appendix
C).
The XDisplay.class (see appendix B.13) extends a common
javax.swing.JPanel which allows for integration into any other com-
mon Java component (e.g. swing.javax.JFrame). It offers two different
constructors:
Once the XDisplay has been created, it starts to live on its own”. The
XDisplay.class implements MD*Crypt’s XQSListener. Assuming that it has
81
XQC in Detail
been registered to the XQServer from its parent class, it obtains informa-
tion regarding results sent back from the server. An obligatory implementa-
tion of the handleServerReply() method filters the relevant XQSObject type
‘GRAPHICS’ and finally creates a new instance of the XPlot.class.
This XPlot.class (see appendix B.14) represents the heart of generating
graphical output. It processes the XQSGraphicsObject that contains infor-
mation about the data that shall be shown, including further properties such
as shape, size and color. A detailed description of components, data and
methods offered by the XQSGraphicsObject is part of section 3.3.2. The
first piece of information XPlot needs to continue is the type of the data
part. XploRe’s Displays are not just meant for showing graphics. Common
textual output could be shown in a Display as well. Each type of data
requires different processing. In the case of graphical data, the minimum
and maximum values of the data need to be determined. This information is
necessary to calculate the size of the plot. Since an XQSDataObject, which
comes as a part of the XQSGraphicsObject, can contain more than one data
part, all data parts must be considered. If the data object consists of three-
dimensional data, the data will also be scaled to a ‘unit cube’. Missing this
step would lead to “odd” results when trying to rotate the plot - points would
“leave” the visible area. For the actual drawing process, Java’s 2D API is
used. This package offers methods for displaying graphics with outline and
fill styles, transforms graphics when they are rendered, constrains rendering
to a particular area, and controls the way graphics look when they are ren-
dered. If the XQSDataObject contains more than one data part, it will be
processed one after another. Output of type ‘text’ is displayed in a font size
that depends on the size of the Display. Before graphical output can be
displayed, information about shape, size and color of the data point need
to be extracted from the XQSDataObject. The actual drawing of the data
point itself is realized within a ‘switch-case’ statement. Figure 4.32 shows
a small extract of the XPlot.class, which demonstrates the ‘birth’ of a single
graphical point.
The variable ‘pLook’ contains information regarding the appearance of the
data point. This information is part of the XQSDataObject that MD*Crypt
has created using the server’s results. A complete overview of possible shapes
is part of section 3.3.2. In case ‘pLook’ contains a ‘0’, no graphical output
is required for the data point; ‘1’ means a simple point; ‘2’ means a non-
filled rectangle; . . . ; ‘4’ means a non-filled triangle. All shapes are realized
using Java’s java.awt.geom.* package. For example, a simple point is an
82
4.2 Programming Structure of the XQC
1 ...
2 switch ( pLook ) {
3 case 0:
4 break ;
5 case 1: // point
6 ellipse2D . setFrame ( xt - 1 , yt - 1 , 2 , 2) ;
7 g2D . fill ( ellipse2D ) ;
8 pol = new Polygon () ;
9 pol . addPoint ( xt + xoff - 1 , yt + yoff - 1) ;
10 pol . addPoint ( xt + xoff + 1 , yt + yoff - 1) ;
11 pol . addPoint ( xt + xoff + 1 , yt + yoff + 1) ;
12 pol . addPoint ( xt + xoff - 1 , yt + yoff + 1) ;
13 toolTip . addElement ( pol ) ;
14 break ;
15 case 2: // r e c t a n g l e
16 rectangle2D . setFrame ( xt - s2 , yt - s2 , s1 , s1 ) ;
17 g2D . draw ( rectangle2D ) ;
18 pol = new Polygon () ;
19 pol . addPoint ( xt + xoff - s2 , yt + yoff - s2 ) ;
20 pol . addPoint ( xt + xoff + s2 , yt + yoff - s2 ) ;
21 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
22 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
23 toolTip . addElement ( pol ) ;
24 break ;
25 ...
26 case 4: // triangle
27 int xtr [] = {
28 xt - s2 , xt , xt + s2 };
29 int ytr [] = {
30 yt + s2 , yt - s2 , yt + s2 };
31 triangle = new GeneralPath ( GeneralPath . WIND_EVEN_ODD , xtr . length ) ;
32 triangle . moveTo ( xtr [0] , ytr [0]) ;
33 for ( int l = 1; l < xtr . length ; l ++) {
34 triangle . lineTo ( xtr [ l ] , ytr [ l ]) ;
35 }
36 triangle . closePath () ;
37 g2D . draw ( triangle ) ;
38 pol = new Polygon () ;
39 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
40 pol . addPoint ( xt + xoff , yt + yoff - s2 ) ;
41 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
42 toolTip . addElement ( pol ) ;
43 break ;
44 ...
45 }
46 ...
83
XQC in Detail
accomplished by drawing a path that includes all three corners of the triangle.
Section 4.1.8 contains a description of additional features offered by the Dis-
play. One of those features is the possibility for showing coordinates of a data
point within a plot by simply pointing the mouse over the shape (see figure
4.24). To realize this feature, we have taken the opportunity to create a tool
tip text for many Java components. A tool tip text is a text that is shown if a
pointing device stays over any point of the component that has implemented
this feature. Unfortunately, this possibility is not offered for graphical Java
components like Ellipse2D or Rectangle2D. One of the Java components that
offers tool tip texts is a javax.swing.JPanel, which also works as a basis for
the XPlot.class. Since a tool tip text should only be shown if the point-
ing device stays over a certain data point, but the data’s coordinates are of
course not identical, an additional logic is required for realization. For this
purpose we use two variables - ‘pol’, which implements a java.awt.Polygon
and ‘toolTip’ as a common vector. Every time a data point gets drawn, the
XPlot.class also creates a polygon with the same coordinates and the same
size as the original data point, and appends it to the vector ‘toolTip’ (see
figure 4.32). Variables ‘xoff’ and ‘yoff’ consider a shifting of coordinates
due to axes that are also shown within the plot. As result, the vector con-
tains information about the representation of every data point on the plot.
The vector is used within the method checkForToolTip(int xtt, int ytt) that
is part of the XPlot.class. This method is called by the event handler class -
XPlotAction.class - every time the pointing device gets moved over the plot
passing over the actual coordinates. If the actual coordinates are inside of
one of the polygons of the vector ‘toolTip’, a tool tip text containing the
data point’s coordinates will be shown.
Another important feature the XPlot.class offers is the possibility to rotate
three-dimensional plots. To realize this feature, the four following matrices
play a significant role:
84
4.2 Programming Structure of the XQC
{0, 1, 0},
{Math.sin(r), 0, Math.cos(r)} }
. . . contains settings for rotating a plot to the left.
1 // Rotate left
2 if ( keyCode == 37) {
3 // System . out . println (" left ") ;
4 double [][] temp = new double [3][3];
5 for ( int i = 0; i < 3; i ++) {
6 for ( int j = 0; j < 3; j ++) {
7 temp [ i ][ j ] = ( rMat [ i ][0] * rMatZX [0][ j ]) +
8 ( rMat [ i ][1] * rMatZX [1][ j ]) + ( rMat [ i ][2] * rMatZX [2][ j ]) ;
9 }
10 }
11 rMat = temp ;
12 repaint () ;
13 }
All four variables contain information, which is used within the rotation
process. Parameter ‘r’ determines the degree of rotation. The actual ro-
tation process is realized within the method rotatePlot(int keyCode, double
85
XQC in Detail
1 // C a l c u l a t e the rotated d a t a p o i n t
2 private void rotate ( int k , int size ) {
3 xRot = new double [ dp . ge t N u m b e rO f R o w s () ];
4 yRot = new double [ dp . ge t N u m b e rO f R o w s () ];
5 zRot = new double [ dp . ge t N u m b e rO f R o w s () ];
6 for ( int i = 0; i < dp . g e t Nu m b e r O f Ro w s () ; i ++) {
7 xRot [ i ] = ( x [ k ][ i ] * rMat [0][0]) + ( y [ k ][ i ] * rMat [1][0]) +
8 ( z [ k ][ i ] * rMat [2][0]) ;
9 yRot [ i ] = ( x [ k ][ i ] * rMat [0][1]) + ( y [ k ][ i ] * rMat [1][1]) +
10 ( z [ k ][ i ] * rMat [2][1]) ;
11 zRot [ i ] = ( x [ k ][ i ] * rMat [0][2]) + ( y [ k ][ i ] * rMat [1][2]) +
12 ( z [ k ][ i ] * rMat [2][2]) ;
13 xRot [ i ] = xRot [ i ] * size / 1.5;
14 yRot [ i ] = yRot [ i ] * size / 1.5;
15 }
16 }
The rotation matrix is needed to calculate the new coordinates of the data
points within the plot. Every data point gets multiplied with the correspond-
ing value of the rotation matrix rMat. Result are rotated data points (xRot,
yRot and zRot) that are shown after repainting the graphic.
In its current version no communication takes place between the GUI compo-
nents Method/Data Window and Display. A challenge for future work
would be to offer the possibility to manipulate data via GUI components
and send those manipulations to the server or to other GUI components. An
example would be the marking or brushing of outliers within plots in order
to have them automatically be marked in the spread sheet as well.
86
4.2 Programming Structure of the XQC
The XploRe Quantlet server offers two dialog objects, which are part of the
XploRe programming language: “read value” and “select item”. Both com-
ponents allow for communication between user and server out of a running
XploRe Quantlet.
Read Value does exactly, what its name implies. It asks the user to pass
a value (or values) to an XploRe Quantlet. This value can then be used
within the Quantlet. Read value is realized by the XReadValue.class (see
appendix B.17). It extends Java’s javax.swing.JDialog to generate a modal
dialog window with the XQC’s Desktop Window as its owner. A modal
window is necessary because the server is waiting, expecting a certain type
of data stream - the result of the Read Value request. Key object of the
communication is MD*Crypt’s XQSReadValueObject. It does not only con-
tain names and default values, the XploRe program is asking for, but it does
also provide a method to send the values back to the server immediately. In
order to react to the user’s input, the XReadValue.class has implemented the
required ActionListener.
Select Item works in a similar manner as Read Value. Instead of expect-
ing the user to enter values he/she is asked to select an item from a list.
The XSelectItem.class (see appendix B.18) also generates a modal dialog
window, but in this case it holds an instance of Java’s javax.swing.JList. It
waits for the user to choose one or more items and to release this selection.
MD*Crypt’s XQSSelectItemObject contains a list with names the user can
select from. The result of the selection is then send back to the server as an
array that contains the status (checked or not checked) of the list items.
87
XQC in Detail
88
Chapter 5
Searching the Internet for net-based statistical solutions leads to three dif-
ferent approaches:
1. CGI techniques,
Using CGI techniques, the user enters data or the location of a data file
via a CGI interface. A statistical program on the server side calculates and
sends back the results to the user. The user will get the results either right
away, shown in the browser window, or the result will be sent to the user
by e-mail. Examples are given by Inoue et al. [IAYY01], the MMM project
(http://macke.wiwi.hu-berlin.de/mmm/) - see also Günther et al. [GMK+ 97]
- and the Rweb project (http://www.math.montana.edu/Rweb/).
89
XQC/XQS Compared to Other Web Based Statistical Solutions
90
5.3 Java Based Client/Server Computing
pure Java implementation of these algorithms, and the more load lies on the
client computer. Computing a nonparametric time series process that con-
tains approximately a thousand observations within a single Java applet is
hardly possible. The computational load of the XQC/XQS model lies on the
server side, which can take advantage of the powerful underlying computer
architecture. This speeds up the computational process significantly. Due to
the communication process which takes place between client and server, the
XQC might take slightly longer to calculate simple statistical problems as
compared to a pure Java applet. But with increasing complexity, the time
saved using the server power exceeds the time needed for the communication
process.
91
XQC/XQS Compared to Other Web Based Statistical Solutions
92
Chapter 6
In today’s world, there hardly exists a field where research is possible with-
out the (mostly extensive) use of computers. “Some of the recent advances
in statistics have even been dependent on advances in computer science and
technology. Many of the currently interesting statistical methods are com-
putationally intensive, either because they require very large numbers of
numerical computations or because they depend on visualization of many
projections of the data.” [Gen03] The financial researcher uses mathemat-
ical and statistical models to predict market behavior; the social scientist
uses it for research about the deployment of the birthrate in Germany; the
physicist uses statistics for modeling the influence that temperature has on
the conductance of copper.
It is desirable for an reader to be able to verify and validate the published re-
sults of statistical research. Even more desirable to an interested researcher,
is the ability to inspect the source code, modify it and produce variations of
the results. Buckheit and Donoho [BD95] outline the topic of Reproducible
Research - “An article about computational science in a scientific publication
is not the scholarship itself, it is merely advertising of the scholarship. The
actual scholarship is the complete software development environment and the
complete set of instructions which generated the figures.” They propose the
publishing of research papers as electronic books, with the inclusion of the
software environment the results were generated with, to make them inter-
actively accessible. Claerbout [Cla02] defines the purpose of reproducibility
93
Reproducible Research Using the XQC/XQS Technology
94
6.1 Types of Presentation
make the entry into the world of scientific research much easier for young
students. They would actually be able to try the programs, change and vary
parameters, or even extend existing programs during their study. On the
other hand, being able to publish results within interactive documents allow
those young researchers to more easily share their results and knowledge with
other scientists.
To summarize, research reproducible can:
• Make research more accurate and more credible, since other researchers
are able to discover any errors and to validate the results.
• Save time for other researchers working on the same or a similar task,
since their research can be built upon validated and expandable results.
95
Reproducible Research Using the XQC/XQS Technology
The simplest form for presenting results of scientific research is a pure textual
description. This form of presentation is limited to the use of algorithms,
formulas and explanations of coherences. A disadvantage of this method
is the presupposed ability of any reader to understand the abstract. This
ability is often needed in order to understand the content, to put oneself
in the author’s position. Using the decathlon example we get the following
results:
The data itself can be presented within a table - see table 6.1.
Decathlete A B C ...
100 m 11.25 10.87 11.18 ...
Long Jump 7.43 7.45 7.44 ...
What are the results of this simple research? Interpreting the calculated
results leads to the conclusion that there seems to be coherence between
the two sports. But without taking a closer look at the data itself, and/or
calculating additional coefficients a “final” conclusion is hardly possible. The
dataset could, for example, contain outliers that influence the results. It
requires additional numbers and explanations to get an image of the actual
coherence. Many readers of those types of publications try to transform
those pure numbers into graphics using their imagination. With this simple
example this might be possible. But imagine, for example, the presentation
of the results of a kernel regression estimate.
96
6.1 Types of Presentation
Figure 6.1: Scatter plots with linear regression and kernel regression estimate
‘Text only’ and ‘graphical presentations’ of scientific results have one thing
in common - it is difficult to determine from where the calculated results and
graphics were derived. Are they an outcome of a mathematical or statistical
software environment or is the presented graphic the result of a graphical
program? We certainly do not want to question published results without
the ability to reproduce them. Nevertheless, the reader has to accept that
the published results really are the outcome of the author’s calculations. An
additional publication of used datasets, the source codes of programs used for
the calculation of results and the creation of graphics, as well as information
regarding the used software environment, are basic approaches for providing
an interested reader at least the opportunity to verify and reproduce the
results. The pure source code is only useful if the reader has access to the
same software, libraries, and methods the author used. But in many cases
97
Reproducible Research Using the XQC/XQS Technology
Figure 6.1 was generated using the software environment XploRe. For this
example, reproducibility could be accomplished by publishing the source code
of the XploRe Quantlet we used. In this case, the reader needs to have access
to this software environment in order to reproduce the figure. In today’s
world, more and more software developers offer access to their software via
Web interfaces. Attaching the source code to an article is the easiest way to
realize reproducibility. The advance of this approach is the independence of
the media from pure paper. There is no need for additional software that
would have to be published as well. The drawback of this approach is the
limitation that the reader cannot regenerate the figure right away but has to
“break out” of the article.
98
6.1 Types of Presentation
Even more useful for many readers, would be the possibility of having access
to the underlying program that generated the calculations and graphics. This
99
Reproducible Research Using the XQC/XQS Technology
feature not only enables the user to validate the author’s results, but the
source code can be used as a basis for further research.
For this form of representation the same drawbacks as for the previous meth-
ods apply - its usage presupposes a publication on interactive media.
• Final conclusions,
100
6.2 Making Research Reproducible
The XploRe Quantlet Client (XQC) represents the front-end of the architec-
ture. The client is fully programmed in Java2, providing an independent and
universal usage. The XQC can be used as an application, as well as running
as an applet within a Web browser. In addition, it is possible to setup the
client to start in certain ways as defined by the author. For this purpose,
a special configuration file is used. The configuration file itself is a simple
ASCII file containing commands. These commands allow starting the XQC
with:
ExecuteProgram = file:///C:/.../QRegression01.xpl
In this case, the XQC starts and executes the stated XploRe Quantlet im-
mediately, but without showing the XploRe code. Path statements can
be maintained as absolute paths, locally (file:///...) or URL address
(http://...), as well as relative to the directory in which the XQC was
started (XQCROOT/...). As a result, a graphic is generated that is identical
to the graphic in the written document (see figure 6.2). Even though it is
the simplest form of reproducibility, a graphic can offers some features, via a
context menu, the pure written document cannot. For example, coordinates
of the data can be shown and for 3D-plots, rotation via cursor keys or mouse
is possible.
If parameters have been used for the computation of results or the generation
of graphics, the author has the choice of extending this form of reproducibil-
ity by utilizing interactive components the XploRe programming language
offers. Using XploRe’s “select item” or “read value” for the Quantlet, the
101
Reproducible Research Using the XQC/XQS Technology
author can offer the opportunity to the reader of changing and adjusting
parameters and/or to influence the results and the graphics of the compu-
tation (see XploRe’s APSS - http://www.i-xplore.de/help/ Xpl Start.html -
for additional information).
OpenData = XQCROOT/decathlon.dat
ShowMethodTree = yes
MethodTreeIniFile = xqc_regression.ini
MethodPath = XQCROOT/xqc_quantlets/
102
6.2 Making Research Reproducible
Child_1 = QRegression02|Regression
The first part, ‘QRegression02’, defines the name of the Quantlet and its
main procedure. The second part, ‘Regression’, represents the name that
is shown within the Method Tree.
Using the parameters stated above, the XQC starts by opening the stated
data set (decathlon.dat) and a method tree that contains the predefined
method (Regression), see figure 6.3.
With this form of representation, the reader is not only able to verify the
data, but also to change data and explore how this affects the regression
coefficients and the graphic. Going one step further, the reader would even
be able to use his/her own data for computation.
An extension of the approach described above is the possibility of editing the
actual XploRe Quantlet that computed the results. Using the parameter
103
Reproducible Research Using the XQC/XQS Technology
OpenInEditor = file:///C:/.../test1.xpl
enables this feature. Immediately after the XQC has been initiated an editor
window opens containing the code. The reader can explore, edit and execute
the program. If the parameter ‘OpenInEditor’ is used, in addition to the
parameter ‘OpenData’, the user can edit both - program and data. Altered
data can be uploaded to the server and used within the Quantlet. Figure
6.4 shows a screenshot of the XQC offering interactivity regarding data and
program.
With this form of reproducibility, the reader has virtually limitless possibili-
ties for verifying research results. The reader is not limited to the program
and data given by the author, but can use his/her own data and program ex-
tensions. Therefore, this could be a potential start point for ongoing research
in the same area. Researches would not have to start from the beginning.
104
6.3 MD*Book
6.3 MD*Book
The client/server structure of XploRe allows for an easy integration of XploRe
programs (Quantlets) into Web pages.
105
Reproducible Research Using the XQC/XQS Technology
With MD*Book, we offer a tool for easily generating electronic books (e-
books) in both formats - PDF and HTML, see Witzel and Klinke [WK02].
106
6.3 MD*Book
The tab strips “execute” and “edit” allow alternate access to the source code.
An inexperienced user would choose “execute”, which will simply execute
the code (simple reproducibility). An experienced user might choose “edit”,
which first shows the source code in the XploRe editor window. Now the
user can modify the code or run it (see figure 6.6).
To ensure that the code on the Web page and the source code at the server
were the same was one of the reasons for developing MD*Book.
At the heart of the MD*Book tool are two developed programs - “tex2sk ”
and “mdbook ”. The program “tex2sk ” decomposes a set of LATEX files and
generates a control file. This control file is used within the program “mdbook ”
to generate all necessary information. It also contains information about the
medium in which the e-book has to be created (e.g. CD-ROM, Internet). An
additional set of parameters in the control file, as well as in the LATEX file
itself, allow for the control of various aspects of the outline and appearance
of the final document.
The program “mdbook ” offers five main options: -ps, -pdf, -html, -java and -
xpl (see figure 6.7) As the names of the options imply, a PostScript document,
a PDF document, or an HTML document, respectively, will be generated.
Whereas the option “-html ” creates HTML documents without the use of
JavaScript, the option “-java” takes advantage of JavaScript functionalities.
The option “-xpl ” generates the “Golden Solution” for XploRe Quantlets as
shown in figure 6.5.
To integrate for a figure, the generating program requires only the integration
of a link to the appropriate Web page with the program.
\begin{verbatim}
motcyc=read("motcyc")
hh=lpregrot(motcyc) ; rule-of-thumb bandwidth
hd=lpderrot(motcyc) ; rule-of-thumb bandwidth
mh=lpregest(motcyc,hh) ; local linear regression
md=lpderest(motcyc,hd) ; local quadratic derivative
mh=setmask(mh,"line","black")
md=setmask(md,"line","blue","dashed")
xy=setmask(motcyc,"cross","small","red")
plot(xy,mh,md)
setgopt(plotdisplay,1,1,"title","Local Polynomial Estimation")
\end{verbatim}
\clink{XLGsmoo12}
107
Reproducible Research Using the XQC/XQS Technology
\begin{figure}[htb]
\begin{center}
\ineps{0.425}{smootherlld}
\caption{Local linear regression (solid), derivative (dashed)
estimate and data.%
\label{smoo_regld}}
\end{center}
\end{figure}
108
Chapter 7
Interactive Teaching -
MM*Stat
109
Interactive Teaching - MM*Stat
7.1 Introduction
MM*Stat is a flexibly applicable tool for supporting the teaching and the
learning process for statistics in basic studies. It is available in different
languages (English, German, French, Spanish, Italian, Czech, Polish and In-
donesian) via the Internet (http://www.md-stat.com), and also published on
CD-ROM. The development of MM*Stat was influenced by the achievement
of the following goals:
2. Statistical analysis in real life can hardly be processed without the use
of computers. A training session should therefore contain the acquisi-
tion of appropriate knowledge regarding computers.
3. Statistics has become more and more “complicated” due to the in-
creasingly complex data structures and the more complex statistical
methods and models. This requires an increasingly differentiated, yet
specialized knowledge, which must, of course, also be part of the teach-
ing process.
110
7.2 Characteristics of MM*Stat
• Third Dimension - Linking contents of the story line with each other.
• Lecture units,
• Additional information,
111
Interactive Teaching - MM*Stat
Sequence of
Lecture Units
1 Additional Information
• Examples,
112
7.4 Additional Information
7.5 Examples
Examples are essential for better understanding of the statistical knowledge
imparted in the lecture units (“Second Dimension”). Therefore great at-
113
Interactive Teaching - MM*Stat
• Enhanced examples,
• Interactive examples.
Not every type of example is offered for each of the lecture units. Buttons
on the lower right corner of the screen indicate what examples are available
for the selected lecture unit. Similar to the additional information, examples
appear on a separate filing card. The user is therefore able to switch between
Lecture card, Information card and Example card at any time. This repre-
sents the great advantage of a filing card system. A superscript tab indicates
the filing card that is currently active.
114
7.5 Examples
Fully explained examples are directly related to the content of the lecture
unit from which they were called. As the name implies, this kind of example
contains a complete explanation of the statistical problem. It begins with a
description of the problem to be solved, followed by an illustration of data
used, and continues with an exact determination of a method to be applied
and the relevant formulas. Fully explained examples also demonstrate the
processed calculations, and finally, give an interpretation of the calculated
results.
Enhanced Examples
All the characteristics described above for the fully explained examples also
apply for the enhanced examples. But this type of example goes one step
further by offering at least one of the following features:
• They are related not only to the lecture unit from which they have
been initiated, but also to previous lecture units.
Interactive Examples
115
Interactive Teaching - MM*Stat
course, and the lack of time. MM*Stat can help to overcome those prob-
lems. The integration of the XploRe Quantlet Client/Server technology into
MM*Stat makes interactivity possible (see section 7.8). Interactive examples
allow the user to practice repeatedly with various variables or data sets, and
with alternate sample sizes or parameters, of the statistical methods applied.
They ensure that the student can actively participate in the learning pro-
cess, enabling him/her to study the effects of “playing” with the statistical
method. In this manner, the student obtains a better understanding of how
the statistical method works.
Figure 7.4 shows a running, interactive example for the lecture unit probabil-
ity distributions . . . normal distribution. In this interactive example, the user
can choose different values for the two parameters expected value and stan-
dard deviation, and observe their effect on the density function of a normal
random variable. The density function of a standard normal distribution is
presented (in black) to provide a further reference point. In addition, the
user can calculate the probability that X falls in some interval.
116
7.6 Reinforcing Previously Learned Statistical Content
A special filing card, Bookmarks, facilitates continuous work within the statis-
tics course. It contains a list of previous filing cards (lecture units, informa-
tion, examples etc.) that have been opened, and allows for jumping directly
into one of these lecture units or examples.
At the end of each topic, MM*Stat offers multiple choice questions. These
questions enable the student to check his/her knowledge. Feedback showing
the results of the answers can be shown on demand. The student can choose
from two different types of feedback: evaluation without indicating errors, or
evaluation indicating errors. Alternatively, the student can force MM*Stat
to check all correct answers.
Some lecture units offer multimedia content, such as audio files. These files
are used for explaining statistical facts or illustrating examples.
MM*Stat also offers a help system that can be accessed via the table of con-
tents filing card. This help system contains technical help (e.g. verification
of whether the computer and browser being used are suitable for MM*Stat),
as well as help for using MM*Stat (e.g. how to open and close filing cards,
etc.).
117
Interactive Teaching - MM*Stat
118
7.9 User Acceptance
1 Server = 127.0.0.1
2 Port = 8888
3
4 executeCommands = func ( " mmeng \\ s226i " )
5 N e v e r S h o w O u t p u t W i n d o w = yes
6 S ho wC o mm a nd Wi n do w = no
MM*Stat has been practically used since 1999, as an additional tool within
a statistics introductory course, and not only used as part of the lecture.
Students can also buy the MM*Stat teach-ware package on CD-ROM. This
enables them to reinforce content learned in class independently. An inquiry
of students attending the class during 1999 revealed that 72 percent already
work with this tool. 75 percent of the students expressed that MM*Stat
helped them to better understand the statistical content.
119
Interactive Teaching - MM*Stat
120
Chapter 8
Conclusions
121
Conclusions
(WSDL) nor XML, for communication between client and server. Instead,
we have defined our own (open) protocol in order to limit the amount of
data that has to be transferred. Despite this difference, our client/server
approach works similarly to what is defined as being a Web Service - a client
that communicates with a server via the Internet using a standardized open
protocol.
As shown in Chapters 6 and 7, our XploRe Quantlet Client/Server architec-
ture has already been successfully used in real life applications. Integrating
the XQC into electronic publications allows for regeneration and reproduc-
tion of statistical results presented within the publication. Being part of the
teach-ware package MM*Stat, the XQC/XQS architecture allows for inter-
activity, supporting teaching and learning statistics in introductory courses.
Our client/server architecture also has its limitations and drawbacks. XQC,
as well as MD*Crypt, rely on a Java Runtime Environment. In order to
access the XploRe Quantlet Server, the user might have to install additional
software on the client’s computer. Another drawback is related to Java’s
applet technology. Since applets are regarded as potential security prob-
lems, some crucial functionality is not allowed by them. Examples of these
restrictions are the disabled copy/paste functionality, and the impossibility
of accessing local files. Running the XQC as a signed applet would help to
overcome these restrictions.
Another well-known problem is the security of data exchanged via the Inter-
net. Data encoding would be a reasonable solution to this security problem,
however, this would slow down the communication process.
The facts mentioned above imply that our XploRe Quantlet Client/Server
architecture still has some challenges that need to be resolved.
122
Bibliography
123
BIBLIOGRAPHY
124
BIBLIOGRAPHY
125
BIBLIOGRAPHY
126
BIBLIOGRAPHY
127
BIBLIOGRAPHY
128
Appendix A
License Agreement
The XploRe Quantlet Client (XQC) can be used free of charge. It does
not come with any support, and is offered to the public in the spirit of the
University of Illinois/NCSA Open Source License:
Copyright (c) 2004 MD*Tech
All rights reserved.
129
License Agreement
130
Appendix B
The following pages contain the source code of selected classes (discussed in
this thesis) that are part of the XploRe Quantlet Client.
B.1 XClient.java
1 package xqc ;
2
3 import javax . swing .*;
4 import com . mdcrypt . mdcrypt .*;
5 import java . awt .*;
6 import java . util .*;
7 import java . awt . datatransfer .*;
8
9 /* *
10 * <p > XClient - main class of the XploRe Q u a n t l et Client </ p >
11 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
12 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
13 * @ v e r s i o n March 2004
14 */
15 class XClient
16 extends JFrame
17 implements XQSListener {
18 protected static String version = " 1.4 " ;
19 protected static String i n t e rn a l V e rs i o n = " 1.4.005 " ;
20 private XClientAction aL = null ;
21 protected static XProperties XOpt = null ;
22 protected static boolean ISAPPLET = true ;
23 protected static boolean I sT r u s t ed A P P L ET = false ;
24 protected static XQServer aXQServer = null ;
25 protected JDesktopPane desktopPane = null ;
26 protected int status = XQSListener . NOT_CONNECTED ;
27 private XConsole aXConsole = null ;
28 protected XOutputFrame aXOutputFrame = null ;
29 private XEditorFrame aXEditorFrame = null ;
30 protected X D a t a M e t h o d F r a m e a X D a t a M e t h o d F r a m e = null ;
31 private JLabel labelLeft = null ;
32 private JLabel labelRight = null ;
33 protected Vector dispList = new Vector () ;
34 protected static int height = 0;
35 protected static int width = 0;
36 private double pSize = 0.9; // default size
37 private JMenu program = null ;
38 private JMenuItem connect = null ;
39 private JMenuItem disconnect = null ;
40 private JMenuItem reconnect = null ;
41 protected static boolean AXIS = true ; // show axis by default
42 protected static int displayHeight = 300; // default height
43 protected static int displayWidth = 300; // default width
131
XQC Source Code
132
B.1 XClient.java
140 else {
141 width = XOpt . width ;
142 if ( width > screenSize . width ) {
143 width = screenSize . width ;
144 }
145 height = XOpt . height ;
146 if ( height > screenSize . height ) {
147 height = screenSize . height ;
148 }
149 }
150
151 if ( XOpt . debugging ) {
152 System . out . println ( " --> setting screen size " ) ;
153 }
154 setSize ( width , height ) ;
155
156 if ( XOpt . debugging ) {
157 System . out . println ( " --> setting menu bar " ) ;
158 }
159 setJMenuBar ( initJMenuBar () ) ;
160 if ( XOpt . debugging ) {
161 System . out . println ( " --> setting content pane " ) ;
162 }
163 se tCo nt ent Pa ne ( i n i t C on t e n t Pa n e () ) ;
164 s e r v e r O b j e c t L i s t = new JList ( s e r v e r O b j e c t L i s t M o d e l ) ;
165 s e r v e r O b j e c t L i s t . setFont ( new Font ( " Monospaced " , Font . BOLD , 14) ) ;
166
167 }
168 catch ( java . lang . Throwable e ) {
169 h a n dl e E x c ep t i o n ( e ) ;
170 }
171
172 /* C a l c u l a t e the screen size */
173 Dimension screenSize = Toolkit . g e t D e f a u l t T o o l k i t () . getScreenSize () ;
174
175 if ( s h o w S p l a s h S c r e e n ) {
176 /* * * * * * * * * * * * * * * * * * * */
177 /* ** SPLASH - SCREEN *** */
178 /* * * * * * * * * * * * * * * * * * * */
179 /* Create the splash screen */
180 if ( XOpt . debugging ) {
181 System . out . println ( " --> creating splash screen " ) ;
182 }
183 ImageIcon image = new ImageIcon ( getClass () . getResource ( " / xqc / intro . gif " ) ) ;
184 XClientIntro aXClientIntro = new XClientIntro ( image ) ;
185 aXClientIntro . pack () ;
186
187 /* Center splash screen */ if ( XOpt . debugging ) {
188 System . out . println ( " --> centering splash screen " ) ;
189 }
190 Dimension s p l a s h S c r e e n S i z e = aXClientIntro . getSize () ;
191 if ( s p l a s h S c r e e n S i z e . height > screenSize . height ) {
192 s p l a s h S c r e e n S i z e . height = screenSize . height ;
193 }
194 if ( s p l a s h S c r e e n S i z e . width > screenSize . width ) {
195 s p l a s h S c r e e n S i z e . width = screenSize . width ;
196 }
197 aXClientIntro . setLocation ( ( screenSize . width - s p l a s h S c r e e n S i z e . width ) / 2 ,
198 ( screenSize . height - s p l a s h S c r e e n S i z e . height ) / 2) ;
199 if ( XOpt . debugging ) {
200 System . out . println ( " --> showing splash screen " ) ;
201 }
202 aXClientIntro . setVisible ( true ) ;
203 try {
204 ;
205 Thread . sleep (3000) ;
206 }
207 catch ( I n t e r r u p t e d E x c e p t i o n ie ) {}
208 ;
209 aXClientIntro . dispose () ;
210
211 /* * * * * * * * * * * * * * * * * * * */
212 /* ** SPLASH - SCREEN *** */
213 /* * * * * * * * * * * * * * * * * * * */
214 }
215
216 /* Center frame on the screen */
217 Dimension frameSize = this . getSize () ;
218 if ( frameSize . height > screenSize . height ) {
219 frameSize . height = screenSize . height ;
220 }
221 if ( frameSize . width > screenSize . width ) {
222 frameSize . width = screenSize . width ;
223 }
224 this . setLocation ( ( screenSize . width - frameSize . width ) / 2 ,
225 ( screenSize . height - frameSize . height ) / 2) ;
226
227 if ( XOpt . debugging ) {
228 System . out . println ( " --> setting XQC frame visible " ) ;
229 }
230 this . setVisible ( true ) ;
231
232 try {
233 if ( XOpt . server != null ) {
234 // connect to server given from ini - file
235 if ( XOpt . debugging ) {
133
XQC Source Code
236 System . out . println ( " --> trying to connect to server " ) ;
237 }
238 getXQServer () . r emo ve Lis te ner ( this ) ;
239 getXQServer () . addListener ( this ) ;
240 getXQServer () . connect () ;
241 if ( getXQServer () . g e t S er v e r St a t u s () == XQSListener . NOT_CONNECTED ) {
242 throw new Exception ( XOpt . XQCA002 ) ;
243 }
244 System . out . println ( " Connected " ) ;
245 }
246 else {
247 this . aL . handleConnect () ;
248 // new XDialog () . s h o w S e r v e r P o r t I n p u t D i a l o g ( this , "0.0.0.0" , 0) ;
249 }
250 }
251 catch ( Exception e ) {
252 System . out . println ( e ) ;
253 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( this , XDialog . ERROR , XOpt . XQCA002 ) ;
254 this . aL . handleConnect () ;
255 // new XDialog () . s h o w S e r v e r P o r t I n p u t D i a l o g ( this , "0.0.0.0" , 0) ;
256 }
257
258 if (! XOpt . ex e c u t eC o m m an d s . equals ( " null " ) ) {
259 // get the c o m m a n d s and execute them
260 if ( XOpt . debugging ) {
261 System . out . println ( " --> executing commands " ) ;
262 }
263 getXQServer () . sendQuantlet ( XOpt . e x e c ut e C o mm a n d s ) ;
264 }
265
266 if (! XOpt . ex ec ute Pr ogr am . equals ( " null " ) ) {
267 // get the program and execute it
268 if ( XOpt . debugging ) {
269 System . out . println ( " --> executing program " ) ;
270 }
271 X H a n d l e I n t e r n e t O p e n programInput = new X H a n d l e I n t e r n e t O p e n ( this , XOpt . executeProgram ,
272 XOpt . XQCA003 + " . xpl " ) ;
273 getXQServer () . sendQuantlet ( programInput . text ) ;
274 }
275
276 if (! XOpt . openInEditor . equals ( " null " ) ) {
277 // get the program and open it in editor
278 if ( XOpt . debugging ) {
279 System . out . println ( " --> opening program in editor " ) ;
280 }
281 X H a n d l e I n t e r n e t O p e n programInput = new X H a n d l e I n t e r n e t O p e n ( this , XOpt . openInEditor ,
282 XOpt . XQCA003 + " . xpl " ) ;
283 aXEditorFrame . setText ( programInput . text ) ;
284 aXEditorFrame . name = programInput . name ;
285 aXEditorFrame . setTitle ( XOpt . XQCA004 + " - " + programInput . name ) ;
286 }
287
288 if (! XOpt . openData . equals ( " null " ) ) {
289 // get the data and open it in D a t a M e t h o d F r a m e
290 if ( XOpt . debugging ) {
291 System . out . println ( " --> opening data set " ) ;
292 }
293 X H a n d l e I n t e r n e t O p e n programInput = new X H a n d l e I n t e r n e t O p e n ( this , XOpt . openData ,
294 XOpt . XQCA003 + " . dat " ) ;
295 a X D a t a M e t h o d F r a m e = new X D a t a M e t h o d F r a m e ( this , programInput . text , 1 , XOpt . withColHeader ) ;
296 a X D a t a M e t h o d F r a m e . name = programInput . name ;
297 a X D a t a M e t h o d F r a m e . setTitle ( XOpt . XQCA005 + " - " + programInput . name ) ;
298 desktopPane . add ( a X D a t a M e t h o d F r a m e ) ;
299 a X D a t a M e t h o d F r a m e . toFront () ;
300 XClientAction . dataNo = XClientAction . dataNo + 1;
301 XClientAction . pos = XClientAction . pos + 1;
302 }
303 }
304
305 private JMenuBar initJMenuBar () {
306 JMenuBar mbar = new JMenuBar () ;
307
308 JMenu xqc = new JMenu () ;
309 xqc . setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . HAND_CURSOR ) ) ;
310 xqc . setName ( " XQC " ) ;
311 xqc . setText ( " XQC " ) ;
312 xqc . setMnemonic ( ’X ’) ;
313 mbar . add ( xqc ) ;
314
315 if (! XOpt . GOLDEN ) {
316 connect = new JMenuItem () ;
317 connect . setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . HAND_CURSOR ) ) ;
318 connect . setName ( " Connect " ) ;
319 connect . s e t A c t i o n C o m m a n d ( " Connect " ) ;
320 connect . setText ( XOpt . XQCA006 ) ;
321 connect . a d d A c t i o n L i s t e n e r ( aL ) ;
322 setConnect () ;
323 xqc . add ( connect ) ;
324
325 disconnect = new JMenuItem () ;
326 disconnect . setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . HAND_CURSOR ) ) ;
327 disconnect . setName ( " Disconnect " ) ;
328 disconnect . s e t A c t i o n C o m m a n d ( " Disconnect " ) ;
329 disconnect . setText ( XOpt . XQCA007 ) ;
330 disconnect . a d d A c t i o n L i s t e n e r ( aL ) ;
331 setDisconnect () ;
134
B.1 XClient.java
135
XQC Source Code
136
B.1 XClient.java
137
XQC Source Code
138
B.1 XClient.java
714 }
715 else {
716 reconnect . setEnabled ( true ) ;
717 }
718 }
719
720 protected void rollBack () {
721 getXQServer () . terminate () ;
722 getXQServer () . r em ove Li ste ner ( this ) ;
723 System . out . println ( " Disconnected " ) ;
724 int n = dispList . size () ;
725 for ( int i = 0; i < n ; i ++) {
726 XDisplayFrame frame = ( XDisplayFrame ) dispList . elementAt ( i ) ;
727 frame . dispose () ; // close all open d i s p l a y s
728 getXQServer () . r em ove Lis te ner ( frame . getDisp () ) ;
729 }
730 dispList . r e m o v e A l l E l e m e n t s () ;
731 dispPos = 1;
732 aL . pos = 1;
733 aL . editorNo = 1;
734 aL . dataNo = 1;
735 if ( this . a X D a t a M e t h o d F r a m e != null ) {
736 this . a X D a t a M e t h o d F r a m e . s e t U p l o a d e d F a l s e () ;
737 }
738 this . s e r v e r O b j e c t L i s t M o d e l . r e m o v e A l l E l e m e n t s () ;
739 this . s e r v e r O b j e c t I n f o r m a t i o n . clear () ;
740 if ( this . aL . s e r v e r O b j e c t L i s t != null ) {
741 this . aL . s e r v e r O b j e c t L i s t . se tDe fa ult Tex t () ;
742 }
743 System . out . println ( " rollback ... done " ) ;
744 }
745
746 public void h a n d l e M d C r y p t E x c e p t i o n ( X Q S S t a t u s M e s s a g e xqsSTM ) {
747 }
748
749 private void h an d l e E xc e p t i on ( java . lang . Throwable exception ) {
750 System . out . println ( " EXCEPTION IN CLASS XClient " + exception ) ;
751 exception . pr i n t S ta c k T r ac e ( System . out ) ;
752 }
753
754 }
139
XQC Source Code
B.2 XClientAction.java
1 package xqc ;
2
3 import javax . swing .*;
4 import com . mdcrypt . mdcrypt .*;
5 import java . awt . event .*;
6 import java . io .*;
7 import java . net .*;
8 import java . util .*;
9 import java . applet . AppletContext ;
10
11 /* *
12 * <p > X C l i e n t A c t i o n - A c t i o n L i s t e n e r for the XClient . class </ p >
13 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
14 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
15 * @ v e r s i on March 2004
16 */
17 class XClientAction
18 extends WindowAdapter
19 implements ActionListener , MouseListener {
20 private XClient client ;
21 public XApplet applet ;
22 static int editorNo = 1; // number of used editor windows
23 static int dataNo = 1; // number of used data windows
24 static int pos = 1; // number of open data & editor windows
25 private String directory = " . " ;
26 private String urlName = " http :// " ; // default url name
27 private String textArea = null ;
28 private String name = null ;
29 private String how = " local " ; // i n d i c a t e s how to open program / data
30 protected X S e r v e r O b j e c t L i s t s e r v e r O b j e c t L i s t = null ;
31 private XDialog dialog = null ;
32
33 protected XClientAction ( XClient client ) {
34 this . client = client ;
35 }
36
37 protected XClientAction ( XClient client , XApplet applet ) {
38 this . client = client ;
39 this . applet = applet ;
40 }
41
42 public void a c t io n P e r fo r m e d ( ActionEvent e1 ) {
43 String arg = e1 . g e t A c t i o n C o m m a n d () ;
44
45 if ( arg . equals ( " Connect " ) ) {
46 handleConnect () ;
47 // i n i t i a l i z e some classes and l i s t e n e r s
48 if ( client . a X D a t a M e t h o d F r a m e != null ) {
49 client . a X D a t a M e t h o d F r a m e . s e t U p l o a d e d F a l s e () ;
50 }
51 int n = client . dispList . size () ;
52 for ( int i = 0; i < n ; i ++) {
53 XDisplayFrame frame = ( XDisplayFrame ) client . dispList . elementAt ( i ) ;
54 frame . dispose () ; // close all open di s p l a y s
55 client . getXQServer () . re mov eL ist ene r ( frame . getDisp () ) ;
56 }
57 client . dispList . r e m o v e A l l E l e m e n t s () ;
58 }
59 if ( arg . equals ( " Disconnect " ) ) {
60 if ( client . status != XQSListener . NOT_CONNECTED ) {
61 client . rollBack () ;
62 client . s e r v e r S t a t u s C h a n g e d ( XQSListener . NOT_CONNECTED ) ;
63 }
64 }
65 if ( arg . equals ( " Reconnect " ) ) {
66 try {
67 if ( client . status != XQSListener . NOT_CONNECTED ) {
68 client . rollBack () ;
69 client . s e r v e r S t a t u s C h a n g e d ( XQSListener . NOT_CONNECTED ) ;
70 client . getXQServer () . addListener ( client ) ;
71 client . getXQServer () . connect () ;
72 System . out . println ( " Connected " ) ;
73 }
74 }
75 catch ( Exception e2 ) {
76 System . out . println ( e2 ) ;
77 }
78 }
79 if ( arg . equals ( " Quit " ) ) {
80 System . out . println ( " Quit " ) ;
81 if ( client . status != XQSListener . NOT_CONNECTED ) {
82 client . getXQServer () . re mov eL ist ene r ( client ) ;
83 client . getXQServer () . terminate () ;
84 client . dispList . r e m o v e A l l E l e m e n t s () ;
85 System . out . println ( " Disconnected " ) ;
86 }
87 client . setVisible ( false ) ;
88 System . out . println ( " Window closed " ) ;
89 if ( client . ISAPPLET == false ) {
90 System . exit (0) ;
91 }
92 }
140
B.2 XClientAction.java
141
XQC Source Code
186 }
187 if ( arg . equals ( " u p l o ad e d O b je c t s " ) ) {
188 if ( client . status == XQSListener . SERVER_READY ) {
189 if ( s e r v e r O b j e c t L i s t == null ) {
190 s e r v e r O b j e c t L i s t = new X S e r v e r O b j e c t L i s t ( client , client . s e r v e r O b j e c t L i s t ) ;
191 client . getXQServer () . addListener ( s e r v e r O b j e c t L i s t ) ;
192 client . desktopPane . add ( s e r v e r O b j e c t L i s t ) ;
193 }
194 else if ( s e r v e r O b j e c t L i s t . isClosed () ) {
195 client . getXQServer () . re mo veL ist en er ( s e r v e r O b j e c t L i s t ) ;
196 s e r v e r O b j e c t L i s t = null ;
197 s e r v e r O b j e c t L i s t = new X S e r v e r O b j e c t L i s t ( client , client . s e r v e r O b j e c t L i s t ) ;
198 client . getXQServer () . addListener ( s e r v e r O b j e c t L i s t ) ;
199 client . desktopPane . add ( s e r v e r O b j e c t L i s t ) ;
200 }
201 s e r v e r O b j e c t L i s t . toFront () ;
202 }
203 else {
204 if ( client . status == XQSListener . SERVER_BUSY ) {
205 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCB004 ) ;
206 }
207 else {
208 if ( client . status == XQSListener . NOT_CONNECTED ) {
209 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCB005 )
;
210 }
211 }
212 }
213 }
214 if ( arg . equals ( " Online Help " ) ) {
215 String url = client . XOpt . onlineHelp ;
216 if ( client . ISAPPLET ) {
217 try {
218 URL u = new URL ( url ) ;
219 AppletContext context = applet . g e t A p p l e t C o n t e x t () ;
220 context . showDocument (u , " onlineHelp " ) ;
221 }
222 catch ( Exception e ) {
223 System . out . println ( " Problems starting onlineHelp ! - " + e ) ;
224 }
225 }
226 else if (! client . ISAPPLET ) {
227 try {
228 String cmd = null ;
229 String os = System . getProperty ( " os . name " ) ;
230 if ( os != null && os . startsWith ( " Windows " ) ) {
231 cmd = " rundll32 url . dll , F i l e P r o t o c o l H a n d l e r " + url ;
232 Process p = Runtime . getRuntime () . exec ( cmd ) ;
233 }
234 else {
235 // Under Unix , N e t s c a p e has to be running for the " - remote "
236 // command to work . So , we try sending the command and
237 // check for an exit value . If the exit command is 0 ,
238 // it worked , o t h e r w i s e we need to start the browser .
239 cmd = " netscape - remote openURL ( " + url + " ) " ;
240 Process p = Runtime . getRuntime () . exec ( cmd ) ;
241 try {
242 // wait for exit code -- if it ’s 0 , command worked ,
243 // o t h e r w i s e we need to start the browser up .
244 int exitCode = p . waitFor () ;
245 if ( exitCode != 0) {
246 // Command failed , start up the browser
247 cmd = " netscape " + url ;
248 p = Runtime . getRuntime () . exec ( cmd ) ;
249 }
250 }
251 catch ( I n t e r r u p t e d E x c e p t i o n e ) {
252 System . err . println ( " Error bringing up browser , cmd = ’ " + cmd + " ’" ) ;
253 System . err . println ( " Caught : " + e ) ;
254 }
255 }
256 }
257 catch ( Exception e ) {
258 System . out . println ( " Unable to start webbrowser ! - " + e . getMessage () ) ;
259 }
260 }
261 }
262 if ( arg . equals ( " About " ) ) {
263 XQSInfoObject infoObject = new XQSInfoObject () ;
264 JTextArea t = new JTextArea ( " XploRe Quantlet Client " ) ;
265 t . append ( " \ nXQC " + XClient . in t e r n al V e r s io n ) ;
266 t . append ( " \ nMD * Crypt Version " + infoObject . g e t M d C r y p t V e r s i o n () ) ;
267 t . append ( " \ nMD * Serv Version " + infoObject . g e t M d S e r v V e r s i o n () ) ;
268 t . append ( " \ nXploRe Server Build " + infoObject . ge tS erv er Bui ld () ) ;
269 t . append ( " \ nJava Version " + System . getProperty ( " java . version " ) ) ;
270 t . append ( " \ n " ) ;
271 t . append ( " \ nCopyright ( c ) 2000 -2004 - MD * Tech " ) ;
272 t . append ( " \ n " ) ;
273 t . append ( " \ nwww .i - XploRe . de " ) ;
274 new XDialog () . s h o w T e x t A r e a C o n f i r m a t i o n D i a l o g ( client , XDialog . MESSAGE , t ) ;
275
276 String str = " \ nDevelopment history :\ n " ;
277 str = str + " \ n1 .4.004 --> 1.4.005 (2004 -02 -15) " ;
278 str = str + " \n - - - - - - - - - - - - - - - - - - - " ;
279 str = str + " \n - Method / Data - Frame can now handle more than just one " ;
280 str = str + " \ n method tree : " ;
142
B.2 XClientAction.java
143
XQC Source Code
144
B.2 XClientAction.java
473
474 public void mousePressed ( MouseEvent e ) {
475 /* * Please do not delete the f o l l o w i n g lines - they are very i m p o r t a n t !!! * */
476 if ( e . getPoint () . distance (122 , 8) <= 6 && e . isControlDown () && e . isAltDown () &&
477 e . getClickCount () == 3) {
478
479 JTextArea t = new JTextArea ( " Authors of the XQC / XQS project :\ n " ) ;
480 t . append ( " \ nHeiko Lehmann - mail@hlehmann . de " ) ;
481 t . append ( " \ nTorsten Kleinow - to r s t e n@ k l e i no w . de " ) ;
482 t . append ( " \ nJoerg Feuerhake - feuerha@wiwi . hu - berlin . de " ) ;
483 t . append ( " \ nRodrigo Witzel - witzel@wiwi . hu - berlin . de " ) ;
484 t . append ( " \ nUwe Ziegenhagen - uwe . zi eg enh ag en@ rz . hu - berlin . de " ) ;
485 new XDialog () . s h o w T e x t A r e a C o n f i r m a t i o n D i a l o g ( client , XDialog . MESSAGE , t ) ;
486 }
487 }
488
489 public void mouseClicked ( MouseEvent e ) {
490 }
491
492 public void mouseReleased ( MouseEvent e ) {
493 }
494
495 public void mouseExited ( MouseEvent e ) {
496 }
497
498 public void mouseEntered ( MouseEvent e ) {
499 }
500
501 }
145
XQC Source Code
B.3 XProperties.java
1 package xqc ;
2
3 import javax . swing .*;
4 import java . io .*;
5 import java . util .*;
6 import java . net .*;
7
8 /* *
9 * <p > X P r o p e r t i e s - reads and handles the . ini file </ p >
10 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
11 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
12 * @ v e r s i o n March 2004
13 */
14 class XProperties
15 extends Properties {
16 private XClient client ;
17 protected String optFileName ;
18 protected int port ;
19 private String portS ;
20 protected String server ;
21 protected boolean showConsole = true ;
22 protected boolean showOutput = true ;
23 protected boolean sh ow Met hod Tr ee = true ;
24 protected String openInEditor = " null " ;
25 protected String e x ec u t e C om m a n d s = " null " ;
26 protected String exe cut eP rog ra m = " null " ;
27 protected String openData = " null " ;
28 protected String d a t a S e t W i t h H e a d e r ;
29 protected boolean withColHeader = false ;
30 protected String Gol den So lut io n ;
31 protected boolean GOLDEN = false ;
32 protected double pSize = 0;
33 protected String pSizeS ;
34 protected int width = 0;
35 protected String widthS ;
36 protected int height = 0;
37 private String heightS ;
38 private String CDROM = null ;
39 protected String XQCROOT = null ;
40 protected String onlineHelp = " http :// www . xplore - stat . de / help / _Xpl_Start . html " ;
41 protected String methodPath ;
42 protected int ma x N o O fC h i l dr e n ;
43 protected String m e t h o d T r e e I n i F i l e = null ;
44 protected Vector treeVector ;
45 protected boolean debugging = false ;
46 protected boolean showStatus = false ;
47
48 private String textFileName = " xqc_language . ini " ;
49 private String XQCText ;
50 // XClient
51 protected String XQCA001 = " Version " ;
52 protected String XQCA002 = " Not able to connect ?! " ;
53 ...
54
55 protected XProperties () {
56 super () ;
57 }
58
59 protected XProperties ( Properties defaults ) {
60 super ( defaults ) ;
61 }
62
63 protected void r e a d L a n g u a g e F i l e () {
64 // open file with text used within the XQC
65 InputStream finText = null ;
66 if (! XClient . ISAPPLET ) {
67 try {
68 finText = new F i l e In p u t St r e a m ( textFileName ) ;
69 }
70 catch ( Exception e ) {
71 System . out . println ( " Using Standard Text --> ENGLISH " ) ;
72 }
73 }
74 else {
75 try {
76 URL iniurl = new URL ( textFileName ) ;
77 URLConnection inicon = iniurl . ope nCo nn ect io n () ;
78 finText = inicon . g etI npu tS tre am () ;
79 }
80 catch ( Exception e ) {
81 System . out . println ( " Using Standard Text --> ENGLISH " ) ;
82 }
83 }
84
85 try {
86 if ( finText != null ) {
87 load ( finText ) ;
88 getXQCText () ;
89 finText . close () ;
90 }
91 }
92 catch ( java . lang . Throwable e ) {
146
B.3 XProperties.java
93 System . out . println ( " Using Standard Text --> ENGLISH " ) ;
94 }
95 }
96
97 protected void rea dO pti onF il e ( XClient client , String optFileName ) {
98 this . client = client ;
99 this . optFileName = optFileName ;
100
101 // open option file
102 InputStream fin = null ;
103 if (! XClient . ISAPPLET ) {
104 try {
105 fin = new Fi l e I n pu t S t r ea m ( optFileName ) ;
106 setROOT ( optFileName ) ;
107 }
108 catch ( F i l e N o t F o u n d E x c e p t i o n e ) {
109 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR ,
110 optFileName + " - " + this . XQCQ001 ) ;
111 System . out . println ( e ) ;
112 }
113 catch ( Exception e ) {
114 System . out . println ( e ) ;
115 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR ,
116 optFileName + " - " + this . XQCQ002 ) ;
117 }
118 }
119 else {
120 try {
121 setROOT ( optFileName ) ;
122 URL iniurl = new URL ( optFileName ) ;
123 URLConnection inicon = iniurl . ope nC onn ect io n () ;
124 fin = inicon . get Inp ut Str ea m () ;
125 }
126 catch ( M a l f o r m e d U R L E x c e p t i o n e ) {
127 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR ,
128 optFileName + " - " + this . XQCQ001 + " " + this . XQCQ003 ) ;
129 System . out . println ( e ) ;
130 }
131 catch ( IOException e ) {
132 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR ,
133 optFileName + " - " + this . XQCQ001 + " " + this . XQCQ004 ) ;
134 System . out . println ( e ) ;
135 }
136 catch ( Exception e ) {
137 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR ,
138 optFileName + " - " + this . XQCQ001 ) ;
139 System . out . println ( e ) ;
140 }
141 }
142
143 try {
144 if ( fin != null ) {
145 load ( fin ) ;
146
147 if ( getProperty ( " Debugging " , " no " ) . toLowerCase () . equals ( " yes " ) ) {
148 debugging = true ;
149 }
150 if ( getProperty ( " S h o w S t a t u s M e s s a g e s " , " no " ) . toLowerCase () . equals ( " yes " ) ) {
151 showStatus = true ;
152
153 }
154 server = getProperty ( " Server " ) ;
155 portS = getProperty ( " Port " ) ;
156 if ( portS != null && ! portS . equals ( " " ) ) {
157 port = Integer . valueOf ( ( String ) getProperty ( " Port " ) ) . intValue () ;
158 }
159 openInEditor = getProperty ( " OpenInEditor " , " null " ) ;
160 if ( (! openInEditor . equals ( " null " ) ) ) {
161 openInEditor = changeROOT ( openInEditor ) ;
162 // new s p e l l i n g
163 }
164 ex ec ute Pr ogr am = getProperty ( " Ex ec ute Pr ogr am " , " null " ) ;
165 if ( (! exe cu teP rog ra m . equals ( " null " ) ) ) {
166 ex ec ute Pro gr am = changeROOT ( ex ec ute Pr ogr am ) ;
167 // old s p e l l i n g
168 }
169 if ( e xec ut ePr ogr am . equals ( " null " ) ) {
170 ex ec ute Pro gr am = getProperty ( " ex ec ute Pro gr am " , " null " ) ;
171 if ( (! exe cu teP ro gra m . equals ( " null " ) ) ) {
172 ex ec ute Pr ogr am = changeROOT ( e xec ut ePr ogr am ) ;
173 }
174 }
175 openData = getProperty ( " OpenData " , " null " ) ;
176 if ( (! openData . equals ( " null " ) ) ) {
177 openData = changeROOT ( openData ) ;
178 }
179 if ( getProperty ( " D a t a S e t W i t h H e a d e r " , " no " ) . toLowerCase () . equals ( " yes " ) ) {
180 withColHeader = true ;
181 // new s p e l l i n g
182 }
183 e x ec u t e C om m a n d s = getProperty ( " Ex e c u te C o m m an d s " , " null " ) ;
184 // old s p e l l i n g
185 if ( ex e c u t eC o m m a nd s . equals ( " null " ) ) {
186 e x e cu t e C o mm a n d s = getProperty ( " ex e c u t eC o m m a nd s " , " null " ) ;
187 }
188 if ( getProperty ( " S h o w C o m m a n d W i n d o w " , " yes " ) . toLowerCase () . equals ( " no " ) ) {
147
XQC Source Code
148
B.3 XProperties.java
149
XQC Source Code
B.4 XApplet.java
1 package xqc ;
2
3 import javax . swing .*;
4 import java . awt .*;
5 import java . awt . event .*;
6 import java . net .*;
7
8 /* *
9 * <p > XApplet - Applet that starts the XploRe Q u a n t l e t Client </ p >
10 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
11 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
12 * @ v e r s i o n March 2004
13 */
14 public class XApplet
15 extends JApplet
16 implements Ac tio nL ist ene r {
17 private XClient client = null ;
18 private String iniFile ;
19 private String startXQC ;
20 private JPanel panel ;
21 private JButton button ;
22 private String xqcStart ;
23 private String xqcEnd ;
24
25 public void init () {
26 iniFile = getParameter ( " iniFile " ) ;
27 startXQC = getParameter ( " startXQC " ) ;
28 xqcStart = getParameter ( " X QC But ton St art " ) ;
29 if ( xqcStart == null ) {
30 xqcStart = " Click to start XQC " ;
31 }
32 xqcEnd = getParameter ( " XQCButtonStop " ) ;
33 if ( xqcEnd == null ) {
34 xqcEnd = " XQC started ... click to stop " ;
35
36 }
37 if ( startXQC == null ) {
38 startXQC = " yes " ;
39 }
40 panel = new JPanel () ;
41 panel . setBackground ( new Color (170 , 170 , 255) ) ;
42 panel . setLayout ( new BorderLayout () ) ;
43 button = new JButton () ;
44 button . setBackground ( new Color (170 , 170 , 255) ) ;
45 button . setFont ( new Font ( " Dialog " , Font . BOLD , 12) ) ;
46 button . a d d A c t i o n L i s t e n e r ( this ) ;
47 button . setVisible ( true ) ;
48 }
49
50 public void start () {
51 if ( startXQC . toLowerCase () . equals ( " no " ) ) {
52 button . setText ( xqcStart ) ;
53 button . s e t A c t i o n C o m m a n d ( " start " ) ;
54 }
55 else {
56 button . setText ( xqcEnd ) ;
57 button . s e t A c t i o n C o m m a n d ( " end " ) ;
58 if ( client == null ) {
59 client = new XClient ( " XQC " , iniFile , true , this ) ;
60 }
61 }
62 panel . add ( button , " Center " ) ;
63 this . get Con te ntP an e () . add ( panel ) ;
64 System . out . println ( " applet initiated " ) ;
65 setName ( " XQC - Applet " ) ;
66 setSize (190 , 35) ;
67 System . out . println ( " applet started " ) ;
68 }
69
70 public void stop () {
71 super . stop () ;
72 this . stopClient () ;
73 }
74
75 public void destroy () {
76 super . destroy () ;
77 System . out . println ( " applet destroyed " ) ;
78 }
79
80 private void stopClient () {
81 if ( client != null ) {
82 if ( client . status != 1006) {
83 try {
84 client . rollBack () ;
85 System . out . println ( " applet stopped " ) ;
86 }
87 catch ( Exception e ) {
88 System . out . println ( " applet stopped ( Exception in ’ rollBack ’) " ) ;
89 }
90 }
91 client . setVisible ( false ) ;
92 }
150
B.4 XApplet.java
93 client = null ;
94 System . out . println ( " client = null " ) ;
95 }
96
97 public void a c t io n P e r fo r m e d ( ActionEvent e ) {
98 String arg = e . g e t A c t i o n C o m m a n d () ;
99 if ( arg . equals ( " start " ) ) {
100 button . setText ( xqcEnd ) ;
101 button . s e t A c t i o n C o m m a n d ( " end " ) ;
102 if ( client == null ) {
103 client = new XClient ( " XQC " , iniFile , false , this ) ;
104 }
105 }
106 else if ( arg . equals ( " end " ) ) {
107 button . setText ( xqcStart ) ;
108 button . s e t A c t i o n C o m m a n d ( " start " ) ;
109 stopClient () ;
110 }
111 }
112
113 }
151
XQC Source Code
B.5 XConsole.java
1 package xqc ;
2
3 import javax . swing .*;
4 import javax . swing . event .*;
5 import java . awt .*;
6 import java . awt . event .*;
7
8 /* *
9 * <p > X C o n s o l e - for single line commands </ p >
10 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
11 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
12 * @ v e r s i o n March 2004
13 */
14 class XConsole
15 extends JI nte rn alF ra me
16 implements ListSelectionListener , KeyListener {
17 private XClient client ;
18 private JTextField textField = null ;
19 private JList list = null ;
20 private D e f a u l t L i s t M o d e l listModel = new D e f a u l t L i s t M o d e l () ;
21
22 protected XConsole ( XClient client ) {
23 super () ;
24 this . client = client ;
25 initialize () ;
26 }
27
28 private void initialize () {
29 int width = XClient . width ;
30 int height = XClient . height ;
31 int y = ( int ) ( height * 0.6) ;
32 width = ( int ) ( width * 0.5 - 15) ;
33 if ( XClient . ISAPPLET == true ) {
34 height = ( int ) ( height - y - 100) ;
35 }
36 else {
37 height = ( int ) ( height - y - 80) ;
38 }
39 setBounds (10 , y , width , height ) ;
40 setFrameIcon ( new ImageIcon ( getClass () . getResource ( " / xqc / xqc . gif " ) ) ) ;
41 setName ( " Console " ) ;
42 setResizable ( true ) ;
43 se tI con ifi ab le ( true ) ;
44 setTitle ( client . XOpt . XQCC001 ) ;
45
46 // creates the List in a S c r o l l P a n e
47 list = new JList ( listModel ) ;
48 list . setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . HAND_CURSOR ) ) ;
49 list . setBackground ( new Color (233 , 233 , 233) ) ;
50 list . s e t S e l e c t i o n M o d e ( L i s t S e l e c t i o n M o d e l . S I N G L E _ S E L E C T I O N ) ;
51 JScrollPane scrollPane = new JScrollPane ( list ) ;
52 list . a d d L i s t S e l e c t i o n L i s t e n e r ( this ) ;
53 list . add Key Li ste ne r ( this ) ;
54
55 // creates the T e x t F i e l d
56 textField = new JTextField () ;
57 textField . setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . TEXT_CURSOR ) ) ;
58 textField . a ddK eyL is ten er ( this ) ;
59
60 JPanel panel = new JPanel () ;
61 panel . setLayout ( new BorderLayout () ) ;
62 panel . add ( scrollPane , " Center " ) ;
63 panel . add ( textField , " South " ) ;
64
65 se tC ont ent Pa ne ( panel ) ;
66 setVisible ( true ) ;
67 }
68
69 public void keyPressed ( KeyEvent e ) {
70 int keyCode = e . getKeyCode () ;
71 if ( keyCode == 10) {
72 if ( client . status == 1003) {
73 String s = textField . getText () ;
74 textField . setText ( " " ) ;
75 if ( s . length () == 0) {
76 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCC002 ) ;
77 }
78 else {
79 parseString ( s ) ;
80 listModel . addElement ( s ) ;
81 // if more than 20 e l e m e n t s - remove the first
82 if ( listModel . getSize () == 21) {
83 listModel . re m o v e El e m e n tA t (0) ;
84 }
85 list . setModel ( listModel ) ;
86 list . e n s u r e I n d e x I s V i s i b l e ( listModel . getSize () - 1) ;
87 System . out . println ( " DirectCommand " ) ;
88 client . getXQServer () . sendQuantlet ( s ) ;
89 }
90 }
91 else if ( client . status == 1004) {
92 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCC003 ) ;
152
B.5 XConsole.java
93 }
94 else if ( client . status == 1006) {
95 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCC004 ) ;
96 }
97 }
98 }
99
100 private void parseString ( String s ) {
101 int i = 0;
102 String tempVariable ;
103 String variable = " " ;
104 while (! " = " . equals ( s . substring (i , i + 1) ) && i < s . length () - 1) {
105 i = i + 1;
106 }
107 if ( i == s . length () - 1) {
108 return ;
109 }
110 while ( " " . equals ( s . substring ( i - 1 , i ) ) && i > 0) {
111 i = i - 1;
112 }
113 if ( i == 0) {
114 return ;
115 }
116 tempVariable = s . substring (0 , i ) ;
117
118 // extract the v a r i a b l e
119 boolean stop = false ;
120 int p = 0;
121 while ( p < tempVariable . length () && ! stop ) {
122 char pStr = tempVariable . charAt ( p ) ;
123 int ascii = pStr ;
124 if ( ( ascii >= 48 && ascii <= 58) ||
125 ( ascii >= 65 && ascii <= 90) ||
126 ( ascii >= 97 && ascii <= 122) ) {
127 variable = variable + pStr ;
128 }
129 else {
130 stop = true ;
131 }
132 p = p + 1;
133 }
134
135 // update S e r v e r O b j e c t L i s t
136 String value ;
137 if (! client . s e r v e r O b j e c t L i s t M o d e l . contains ( variable ) ) {
138 client . s e r v e r O b j e c t L i s t M o d e l . addElement ( variable ) ;
139 int size = client . s e r v e r O b j e c t L i s t M o d e l . getSize () - 1;
140 client . s e r v e r O b j e c t L i s t . e n s u r e I n d e x I s V i s i b l e ( size ) ;
141 value = " \ ’ " + variable + " \ ’ - " + client . XOpt . XQCC005 + " :\ n " ;
142 value = value + s + " \ n " ;
143 client . s e r v e r O b j e c t I n f o r m a t i o n . put ( variable , value ) ;
144 }
145 else {
146 value = ( String ) client . s e r v e r O b j e c t I n f o r m a t i o n . get ( variable ) ;
147 value = value + " \ n \ ’ " + variable + " \ ’ - " + client . XOpt . XQCC006 + " :\ n " ;
148 value = value + s + " \ n " ;
149 client . s e r v e r O b j e c t I n f o r m a t i o n . put ( variable , value ) ;
150 }
151 }
152
153 public void keyReleased ( KeyEvent e ) {
154 }
155
156 public void keyTyped ( KeyEvent e ) {
157 }
158
159 public void valueChanged ( L i s t S e l e c t i o n E v e n t e ) {
160 String s = ( String ) list . g e t S e l e c t e d V a l u e () ;
161 textField . setText ( s ) ;
162 }
163
164 }
153
XQC Source Code
B.6 XEditorFrame.java
1 package xqc ;
2
3 import javax . swing .*;
4 import javax . swing . event .*;
5 import java . awt . event .*;
6 import java . awt .*;
7 import java . io .*;
8
9 /* *
10 * <p > X E d i t o r F r a m e - for writing your own quantlets </ p >
11 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
12 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
13 * @ v e r s i o n March 2004
14 */
15 class XEditorFrame
16 extends JI nte rn alF ra me
17 implements InternalFrameListener , Act io nLi ste ne r {
18 public String name ;
19 private String directory = " . " ;
20 private JTextArea textArea = null ;
21 private XClient client = null ;
22 private int editorNo ;
23 private int width = XClient . width ;
24 private int height = XClient . height ;
25 private int pos = XClientAction . pos ;
26
27 protected XEditorFrame ( XClient client , int editorNo ) {
28 super () ;
29 this . a d d I n t e r n a l F r a m e L i s t e n e r ( this ) ;
30 this . client = client ;
31 this . editorNo = editorNo ;
32 this . pos = pos ;
33 name = client . XOpt . XQCM001 + ( editorNo ) + " . xpl " ;
34 initialize () ;
35 }
36
37 private void initialize () {
38 try {
39 if ( pos == 10) {
40 XClientAction . pos = 0;
41 }
42 int x = 10 + ( pos - 1) * 20;
43 int w = ( int ) ( width * 0.5 - 15) ;
44 int h = ( int ) ( height * 0.6 - 20) ;
45 setBounds (x , x , w , h ) ;
46 setFrameIcon ( new ImageIcon ( getClass () . getResource ( " / xqc / xqc . gif " ) ) ) ;
47 setName ( " Editor " ) ;
48 setResizable ( true ) ;
49 se tI con if iab le ( true ) ;
50 se tM axi mi zab le ( true ) ;
51 setClosable ( true ) ;
52 setTitle ( client . XOpt . XQCM002 + " - " + name ) ;
53
54 ImageIcon execicon = new ImageIcon ( getClass () . getResource ( " / xqc / execute . gif " ) ) ;
55 ImageIcon execicon1 = new ImageIcon ( getClass () . getResource ( " / xqc / execute - on . gif " ) ) ;
56 XButton exe = new XButton ( execicon , execicon1 ) ;
57 exe . s et Too lTi pT ext ( client . XOpt . XQCM003 ) ;
58 exe . s e t A c t i o n C o m m a n d ( " Execute " ) ;
59 exe . a d d A c t i o n L i s t e n e r ( this ) ;
60
61 ImageIcon saveicon = new ImageIcon ( getClass () . getResource ( " / xqc / save . gif " ) ) ;
62 ImageIcon saveicon1 = new ImageIcon ( getClass () . getResource ( " / xqc / save - on . gif " ) ) ;
63 XButton save = new XButton ( saveicon , saveicon1 ) ;
64 save . s et Too lT ipT ext ( client . XOpt . XQCM004 ) ;
65 save . s e t A c t i o n C o m m a n d ( " Save " ) ;
66 save . a d d A c t i o n L i s t e n e r ( this ) ;
67
68 JPanel menu = new JPanel () ;
69 menu . setLayout ( new FlowLayout ( FlowLayout . LEFT ) ) ;
70 menu . setBackground ( new Color (222 , 222 , 222) ) ;
71 menu . add ( exe ) ;
72 if (! client . ISAPPLET || ( client . ISAPPLET && client . Is T r u s te d A P P LE T ) ) {
73 menu . add ( save ) ;
74 }
75
76 textArea = new JTextArea () ;
77 textArea . setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . TEXT_CURSOR ) ) ;
78
79 JScrollPane scrollPane = new JScrollPane () ;
80 scrollPane . s e t Vi e w p o rt V i e w ( textArea ) ;
81
82 JPanel panel = new JPanel () ;
83 panel . setLayout ( new BorderLayout () ) ;
84 panel . add ( menu , " North " ) ;
85 panel . add ( scrollPane , " Center " ) ;
86
87 se tC ont en tPa ne ( panel ) ;
88 setVisible ( true ) ;
89
90 }
91 catch ( java . lang . Throwable exc ) {
92 h a nd l e E x ce p t i o n ( exc ) ;
154
B.6 XEditorFrame.java
93 }
94 }
95
96 public void setText ( String text ) {
97 textArea . setText ( text ) ;
98 }
99
100 public void a c t io n P e r fo r m e d ( ActionEvent e ) {
101 String arg = e . g e t A c t i o n C o m m a n d () ;
102
103 if ( arg . equals ( " Execute " ) ) {
104 if ( client . status == 1003) {
105 String s = textArea . getText () ;
106 if ( s . length () == 0) {
107 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCM005 ) ;
108 }
109 else {
110 client . getXQServer () . sendQuantlet ( s ) ;
111 }
112 }
113 else if ( client . status == 1004) {
114 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCM006 ) ;
115 }
116 else if ( client . status == 1006) {
117 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCM007 ) ;
118 }
119 }
120
121 if ( arg . equals ( " Save " ) ) {
122 JFileChooser d = new JFileChooser () ;
123 d . s e t S e le c t e d Fi l e ( new File ( name ) ) ;
124 d . s e t C u r r e n t D i r e c t o r y ( new File ( directory ) ) ;
125 d . a d d C h o o s a b l e F i l e F i l t e r ( new XFilterXPL () ) ;
126 int returnVal = d . sh owS av eDi al og ( client ) ;
127 if ( returnVal == JFileChooser . A PP ROV E_ OPT ION ) {
128 File file = d . g e t Se l e c t ed F i l e () ;
129 directory = d . ge t S e l ec t e d Fi l e () . g e tA b s o l ut e P a t h () ;
130 try {
131 textArea . write ( new PrintWriter ( new FileWriter ( file ) ) ) ;
132 }
133 catch ( IOException io ) {
134 System . out . println ( " IOException : " + io ) ;
135 }
136 name = file . getName () ;
137 setTitle ( client . XOpt . XQCM002 + " - " + name ) ;
138 this . show () ;
139 }
140 }
141 }
142
143 public void i n t e r n a l F r a m e C l o s i n g ( I n t e r n a l F r a m e E v e n t e ) {
144 XClientAction . pos = XClientAction . pos - 1;
145 }
146
147 public void i n t e r n a l F r a m e C l o s e d ( I n t e r n a l F r a m e E v e n t e ) {
148 }
149
150 public void i n t e r n a l F r a m e O p e n e d ( I n t e r n a l F r a m e E v e n t e ) {
151 }
152
153 public void i n t e r n a l F r a m e I c o n i f i e d ( I n t e r n a l F r a m e E v e n t e ) {
154 }
155
156 public void i n t e r n a l F r a m e D e i c o n i f i e d ( I n t e r n a l F r a m e E v e n t e ) {
157 this . toFront () ;
158 }
159
160 public void i n t e r n a l F r a m e A c t i v a t e d ( I n t e r n a l F r a m e E v e n t e ) {
161 }
162
163 public void i n t e r n a l F r a m e D e a c t i v a t e d ( I n t e r n a l F r a m e E v e n t e ) {
164 }
165
166 private void h an d l e E xc e p t i on ( java . lang . Throwable exception ) {
167 System . out . println ( " - - - - - - - - - UNCAUGHT EXCEPTION - - - - - - - - - " ) ;
168 exception . pr i n t S ta c k T r ac e ( System . out ) ;
169 }
170
171 }
155
XQC Source Code
B.7 XOutputFrame.java
1 package xqc ;
2
3 import javax . swing .*;
4 import com . mdcrypt . mdcrypt .*;
5 import java . awt .*;
6 import java . awt . event .*;
7
8 /* *
9 * <p > X O u t p u t F r a m e - p r e s e n t s server ( text ) output </ p >
10 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
11 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
12 * @ v e r s i o n March 2004
13 */
14 class XOutputFrame
15 extends JI nte rn alF ra me
16 implements XQSListener , Ac tio nL ist en er {
17 private XClient client = null ;
18 private JPanel contentPane = null ;
19 private JScrollPane scrollPane = null ;
20 protected JTextArea textArea = null ;
21
22 protected XOutputFrame ( XClient client ) {
23 super () ;
24 this . client = client ;
25 initialize () ;
26 }
27
28 private void initialize () {
29 try {
30 int width = XClient . width ;
31 int height = XClient . height ;
32 int x = ( int ) ( width * 0.5 + 5) ;
33 width = ( int ) ( width * 0.5 - 25) ;
34 if ( XClient . ISAPPLET == true ) {
35 height = ( int ) ( height - 110) ;
36 }
37 else {
38 height = ( int ) ( height - 90) ;
39 }
40 setBounds (x , 10 , width , height ) ;
41 setFrameIcon ( new ImageIcon ( getClass () . getResource ( " / xqc / xqc . gif " ) ) ) ;
42 setName ( " OutputFrame " ) ;
43 setTitle ( client . XOpt . XQCP001 ) ;
44 se tI con if iab le ( true ) ;
45 se tM axi mi zab le ( true ) ;
46 setResizable ( true ) ;
47
48 // clear button
49 ImageIcon clearicon = new ImageIcon ( getClass () . getResource ( " / xqc / clear . gif " ) ) ;
50 ImageIcon clearicon1 = new ImageIcon ( getClass () . getResource ( " / xqc / clear - on . gif " ) ) ;
51 XButton cls = new XButton ( clearicon , clearicon1 ) ;
52 cls . s et Too lTi pT ext ( client . XOpt . XQCP002 ) ;
53 cls . s e t A c t i o n C o m m a n d ( " Clear " ) ;
54 cls . a d d A c t i o n L i s t e n e r ( this ) ;
55
56 JPanel menu = new JPanel () ;
57 menu . setLayout ( new FlowLayout ( FlowLayout . LEFT ) ) ;
58 menu . setBackground ( new Color (222 , 222 , 222) ) ;
59 menu . add ( cls ) ;
60
61 // create the T e x tA r e a
62 textArea = new JTextArea () ;
63 textArea . setName ( " XO u t p u tT e x t A re a " ) ;
64 textArea . setBackground ( new Color (233 , 233 , 233) ) ;
65 textArea . setEditable ( false ) ;
66 textArea . setText ( client . XOpt . XQCP003 + " \ n " + XClient . version + " \ n \ n " ) ;
67
68 // create the S c r o l l P a n e
69 scrollPane = new JScrollPane () ;
70 scrollPane . setName ( " X O u t p u t S c r o l l P a n e " ) ;
71 scrollPane . s e t Vi e w p o rt V i e w ( textArea ) ;
72
73 // create the C o n t e n t P a n e
74 contentPane = new JPanel () ;
75 contentPane . setName ( " X O u t p u t F r a m e C o n t e n t P a n e " ) ;
76 contentPane . setLayout ( new BorderLayout () ) ;
77 contentPane . add ( menu , " North " ) ;
78 contentPane . add ( scrollPane , " Center " ) ;
79
80 se tC ont en tPa ne ( contentPane ) ;
81 setVisible ( true ) ;
82
83 }
84 catch ( java . lang . Throwable ivjExc ) {
85 h a nd l e E x ce p t i o n ( ivjExc ) ;
86 }
87 }
88
89 public XQSObject h a n d l e S e r v e r R e p l y ( XQSObject x ) {
90 if ( x . getType () == XQSObject . OUTPUT && ! client . s e r v e r O b j e c t L i s t T e x t O u t p u t ) {
91 System . out . println ( " TextOutput " ) ;
92 X Q SO u t p u tO b j e c t xout = ( X Q S O ut p u t O bj e c t ) x ;
156
B.7 XOutputFrame.java
157
XQC Source Code
B.8 XDataMethodFrame.java
1 package xqc ;
2
3 import javax . swing .*;
4 import javax . swing . event .*;
5 import javax . swing . tree .*;
6 import java . awt .*;
7 import java . util .*;
8 import javax . swing . table .*;
9
10 /* *
11 * <p > X D a t a M e t h o d F r a m e - GUI - holds a method - tree and a table - model </ p >
12 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
13 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
14 * @ v e r s i o n March 2004
15 */
16 class X D a t a M e t h o d F r a m e
17 extends JI nte rn alF ra me
18 implements I n t e r n a l F r a m e L i s t e n e r {
19 private X D a t a M e t h o d A c t i o n aL ;
20 private XClient client = null ;
21 private int dataNo ;
22 private int width = XClient . width ;
23 private int height = XClient . height ;
24 private int pos = XClientAction . pos ;
25 protected String name ;
26 protected String dataName ;
27 protected String dataSetName ;
28 private int rows = 0;
29 private int cols = 0;
30 private String [][] data ;
31 private X D a t a Ta b l e M od e l tableModel ;
32 protected D e f a u l t T a b l e C o l u m n M o d e l columnModel ;
33 protected TableColumn column ;
34 protected JTable table ;
35 private D e f a u l t M u t a b l e T r e e N o d e root ;
36 private D e f a u l t M u t a b l e T r e e N o d e child ;
37 private D e f a u l t M u t a b l e T r e e N o d e subChild ;
38 protected JTree tree ;
39 private T r e e S e l e c t i o n M o d e l tsm ;
40 private JSplitPane splitPane ;
41 private JScrollPane s c r ol l P a n eR i g h t ;
42 private JScrollPane scr ol lPa neL ef t ;
43 protected X D a t a M e t h o d F r a m e T r e e newTreeModel ;
44 private boolean withColHeader = false ; // column header
45 private String [] colHeader ; // column header
46 private XDialog dialog = null ;
47
48 public X D a t a M e t h o d F r a m e ( XClient client , int dataNo ) {
49 super () ;
50 this . a d d I n t e r n a l F r a m e L i s t e n e r ( this ) ;
51 dialog = new XDialog () ;
52 dialog . s h o w R o w C o l I n p u t D i a l o g ( client ) ;
53 rows = dialog . rows ;
54 cols = dialog . cols ;
55 if ( rows <= 0 || cols <= 0) {
56 return ;
57 }
58 else {
59 data = new String [ rows ][ cols ];
60 this . client = client ;
61 this . dataNo = dataNo ;
62 this . pos = pos ;
63 initialize () ;
64 }
65 }
66
67 public X D a t a M e t h o d F r a m e ( XClient client , int rows , int cols , int dataNo ) {
68 super () ;
69 this . a d d I n t e r n a l F r a m e L i s t e n e r ( this ) ;
70 this . rows = rows ;
71 this . cols = cols ;
72 if ( rows <= 0 || cols <= 0) {
73 return ;
74 }
75 else {
76 data = new String [ rows ][ cols ];
77 this . client = client ;
78 this . dataNo = dataNo ;
79 this . pos = pos ;
80 initialize () ;
81 }
82 }
83
84 public X D a t a M e t h o d F r a m e ( XClient client , String dataString , int dataNo , boolean withColHeader ) {
85 super () ;
86 this . a d d I n t e r n a l F r a m e L i s t e n e r ( this ) ;
87 data = stringToTable ( dataString ) ;
88 this . client = client ;
89 this . dataNo = dataNo ;
90 this . withColHeader = withColHeader ;
91 this . pos = pos ;
92 initialize () ;
158
B.8 XDataMethodFrame.java
93 if ( withColHeader ) {
94 setColHeader (0) ;
95 }
96 aL . d a t a U p l o a d C h e c k T r u e () ;
97 }
98
99 private void initialize () {
100 name = client . XOpt . XQCD001 + ( dataNo ) + " . dat " ;
101 dataName = client . XOpt . XQCD001 + ( dataNo ) ;
102
103 // data - set name - used for the methods
104 dataSetName = " DataSetNumber " + dataNo ;
105
106 aL = new X D a t a M e t h o d A c t i o n ( this , client ) ;
107
108 if ( pos == 10) {
109 XClientAction . pos = 0;
110 }
111 int x = 10 + ( pos - 1) * 20;
112 int w = ( int ) ( width * 0.5 - 15) ;
113 int h = ( int ) ( height * 0.6 - 20) ;
114 setBounds (x , x , w , h ) ;
115 setFrameIcon ( new ImageIcon ( getClass () . getResource ( " / xqc / xqc . gif " ) ) ) ;
116 setName ( client . XOpt . XQCD002 ) ;
117 setResizable ( true ) ;
118 se tI con ifi ab le ( true ) ;
119 se tM axi miz ab le ( true ) ;
120 setClosable ( true ) ;
121 setTitle ( client . XOpt . XQCD002 + " - " + name ) ;
122
123 JPanel menu = new JPanel () ;
124 menu . setLayout ( new FlowLayout ( FlowLayout . LEFT ) ) ;
125 menu . setBackground ( new Color (222 , 222 , 222) ) ;
126
127 if ( client . XOpt . treeVector != null ) {
128 if ( client . XOpt . treeVector . size () >= 1) {
129 ImageIcon treeicon = new ImageIcon ( getClass () . getResource ( " / xqc / tree . gif " ) ) ;
130 ImageIcon treeicon1 = new ImageIcon ( getClass () . getResource ( " / xqc / tree - on . gif " ) ) ;
131 XButton treei = new XButton ( treeicon , treeicon1 ) ;
132 treei . s et Too lTi pT ext ( client . XOpt . XQCD010 ) ;
133 treei . s e t A c t i o n C o m m a n d ( " Tree " ) ;
134 treei . a d d A c t i o n L i s t e n e r ( aL ) ;
135 menu . add ( treei ) ;
136 }
137 }
138
139 ImageIcon uploadicon = new ImageIcon ( getClass () . getResource ( " / xqc / upload . gif " ) ) ;
140 ImageIcon uploadicon1 = new ImageIcon ( getClass () . getResource ( " / xqc / upload - on . gif " ) ) ;
141 XButton upl = new XButton ( uploadicon , uploadicon1 ) ;
142 upl . s etT oo lTi pT ext ( client . XOpt . XQCD003 ) ;
143 upl . s e t A c t i o n C o m m a n d ( " UpLoad " ) ;
144 upl . a d d A c t i o n L i s t e n e r ( aL ) ;
145 menu . add ( upl ) ;
146
147 if (! client . ISAPPLET || ( client . ISAPPLET && client . Is T r u s te d A P P LE T ) ) {
148 ImageIcon saveicon = new ImageIcon ( getClass () . getResource ( " / xqc / save . gif " ) ) ;
149 ImageIcon saveicon1 = new ImageIcon ( getClass () . getResource ( " / xqc / save - on . gif " ) ) ;
150 XButton save = new XButton ( saveicon , saveicon1 ) ;
151 save . set Too lT ipT ex t ( client . XOpt . XQCD004 ) ;
152 save . s e t A c t i o n C o m m a n d ( " Save " ) ;
153 save . a d d A c t i o n L i s t e n e r ( aL ) ;
154 menu . add ( save ) ;
155
156 ImageIcon copyicon = new ImageIcon ( getClass () . getResource ( " / xqc / copy . gif " ) ) ;
157 ImageIcon copyicon1 = new ImageIcon ( getClass () . getResource ( " / xqc / copy - on . gif " ) ) ;
158 XButton copy = new XButton ( copyicon , copyicon1 ) ;
159 copy . set Too lT ipT ex t ( client . XOpt . XQCD005 ) ;
160 copy . s e t A c t i o n C o m m a n d ( " Copy " ) ;
161 copy . a d d A c t i o n L i s t e n e r ( aL ) ;
162 menu . add ( copy ) ;
163
164 ImageIcon pasteicon = new ImageIcon ( getClass () . getResource ( " / xqc / paste . gif " ) ) ;
165 ImageIcon pasteicon1 = new ImageIcon ( getClass () . getResource ( " / xqc / paste - on . gif " ) ) ;
166 XButton paste = new XButton ( pasteicon , pasteicon1 ) ;
167 paste . s et Too lT ipT ext ( client . XOpt . XQCD006 ) ;
168 paste . s e t A c t i o n C o m m a n d ( " Paste " ) ;
169 paste . a d d A c t i o n L i s t e n e r ( aL ) ;
170 menu . add ( paste ) ;
171 }
172
173 ImageIcon colselicon = new ImageIcon ( getClass () . getResource ( " / xqc / colsel . gif " ) ) ;
174 ImageIcon colselicon1 = new ImageIcon ( getClass () . getResource ( " / xqc / colsel - on . gif " ) ) ;
175 XButton colSel = new XButton ( colselicon , colselicon1 ) ;
176 colSel . s etT oo lTi pT ext ( client . XOpt . XQCD007 ) ;
177 colSel . s e t A c t i o n C o m m a n d ( " ColSelMode " ) ;
178 colSel . a d d A c t i o n L i s t e n e r ( aL ) ;
179 menu . add ( colSel ) ;
180
181 ImageIcon cellselicon = new ImageIcon ( getClass () . getResource ( " / xqc / cellsel . gif " ) ) ;
182 ImageIcon cellselicon1 = new ImageIcon ( getClass () . getResource ( " / xqc / cellsel - on . gif " ) ) ;
183 XButton cellSel = new XButton ( cellselicon , cellselicon1 ) ;
184 cellSel . se tTo ol Tip Te xt ( client . XOpt . XQCD008 ) ;
185 cellSel . s e t A c t i o n C o m m a n d ( " CellSelMode " ) ;
186 cellSel . a d d A c t i o n L i s t e n e r ( aL ) ;
187 menu . add ( cellSel ) ;
188
159
XQC Source Code
160
B.8 XDataMethodFrame.java
161
XQC Source Code
162
B.8 XDataMethodFrame.java
163
XQC Source Code
B.9 XDataMethodAction.java
1 package xqc ;
2
3 import java . awt .*;
4 import java . awt . event .*;
5 import java . awt . datatransfer .*;
6 import javax . swing .*;
7 import javax . swing . event .*;
8 import javax . swing . tree . TreePath ;
9 import java . util .*;
10 import java . io .*;
11 import javax . swing . table .*;
12 import com . mdcrypt . mdcrypt .*;
13
14 /* *
15 * <p > X D a t a M e t h o d A c t i o n - A c t i o n L i s t e n e r for XD a t a M e t h o d F r a m e </ p >
16 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
17 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
18 * @ v e r s i on March 2004
19 */
20 class X D a t a M e t h o d A c t i o n
21 implements ActionListener , MouseListener , TreeSelectionListener , TableModelListener ,
22 TableColumnModelListener {
23 private XClient client = null ;
24 private X D a t a M e t h o d F r a m e d a t a M et h o d Fr a m e ;
25 private String directory = " . " ;
26 private JPopupMenu popup = null ;
27 private ButtonGroup bg = null ;
28 private JMenuItem selectNon = null ;
29 private JMenuItem selectCol = null ;
30 private JMenuItem selectRow = null ;
31 private JMenuItem selectCell = null ;
32 private boolean UPLOADED = false ;
33 // to handle tree value changed
34 private boolean TSE = true ;
35 // holds the event for a d d i t i o n a l mouse - clicks
36 private T r e e S e l e c t i o n E v e n t tsEvent , tsEventM ;
37 private KeyStroke copy ;
38 private KeyStroke paste ;
39 private Clipboard system ;
40 private boolean c l i pb o a r d Ac c e s s = false ;
41 private S t r i n gS e l e c ti o n stsel ;
42 private double [][] doubleData ;
43 private String [][] uploadData ;
44 private X Q C D o ub l e M a tr i x doubleMatrix = null ;
45 private Point point1 = new Point () ;
46 private Point point2 = new Point () ;
47
48 protected X D a t a M e t h o d A c t i o n ( X D a t a M e t h o d F r a m e dataMethodFrame , XClient client ) {
49 this . client = client ;
50 this . d a ta M e t h od F r a m e = d a t a M et h o d F ra m e ;
51
52 copy = KeyStroke . getKeyStroke ( KeyEvent . VK_C , ActionEvent . CTRL_MASK , false ) ;
53 paste = KeyStroke . getKeyStroke ( KeyEvent . VK_V , ActionEvent . CTRL_MASK , false ) ;
54
55 try {
56 system = Toolkit . g e t D e f a u l t T o o l k i t () . g e t S y s t e m C l i p b o a r d () ;
57 c l ip b o a r dA c c e s s = true ;
58 }
59 catch ( Exception e ) {
60 c l ip b o a r dA c c e s s = false ;
61 }
62
63 popup = new JPopupMenu () ;
64
65 if ( c li p b o a rd A c c es s ) {
66
67 JMenuItem copy = new JMenuItem ( client . XOpt . XQCF001 ) ;
68 copy . s e t A c t i o n C o m m a n d ( " Copy " ) ;
69 copy . a d d A c t i o n L i s t e n e r ( this ) ;
70 popup . add ( copy ) ;
71
72 JMenuItem paste = new JMenuItem ( client . XOpt . XQCF002 ) ;
73 paste . s e t A c t i o n C o m m a n d ( " Paste " ) ;
74 paste . a d d A c t i o n L i s t e n e r ( this ) ;
75 popup . add ( paste ) ;
76
77 popup . addSeparator () ;
78 }
79
80 bg = new ButtonGroup () ;
81
82 selectNon = new JMenuItem ( client . XOpt . XQCF003 ) ;
83 selectNon . s e t A c t i o n C o m m a n d ( " No Selection Mode " ) ;
84 selectNon . a d d A c t i o n L i s t e n e r ( this ) ;
85 popup . add ( selectNon ) ;
86
87 selectCol = new JMenuItem ( client . XOpt . XQCF004 ) ;
88 selectCol . s e t A c t i o n C o m m a n d ( " Column Selection Mode " ) ;
89 selectCol . a d d A c t i o n L i s t e n e r ( this ) ;
90 popup . add ( selectCol ) ;
91
92 selectCell = new JMenuItem ( client . XOpt . XQCF005 ) ;
164
B.9 XDataMethodAction.java
165
XQC Source Code
189 }
190
191 if ( arg . equals ( " CellSelMode " ) ) {
192 if (! d a t aM e t h o dF r a m e . table . g e t C e l l S e l e c t i o n E n a b l e d () ) {
193 d a ta M e t h od F r a m e . table . s e t C e l l S e l e c t i o n E n a b l e d ( true ) ;
194 d a ta M e t h od F r a m e . table . s e t R o w S e l e c t i o n A l l o w e d ( true ) ;
195 d a ta M e t h od F r a m e . table . s e t C o l u m n S e l e c t i o n A l l o w e d ( true ) ;
196 d a ta M e t h od F r a m e . table . repaint () ;
197 }
198 else {
199 d a ta M e t h od F r a m e . table . s e t C e l l S e l e c t i o n E n a b l e d ( false ) ;
200 d a ta M e t h od F r a m e . table . s e t R o w S e l e c t i o n A l l o w e d ( false ) ;
201 d a ta M e t h od F r a m e . table . s e t C o l u m n S e l e c t i o n A l l o w e d ( false ) ;
202 d a ta M e t h od F r a m e . table . repaint () ;
203 }
204 }
205
206 if ( arg . equals ( " UpLoad " ) ) {
207 if ( da t a M e th o d F r am e . getClient () . status == 1003) {
208
209 XDialog dialog = new XDialog () ;
210 dialog . s h o w S t r i n g I n p u t D i a l o g ( client , client . XOpt . XQCF014 + " : " , null ) ;
211 String ret = dialog . ret ;
212
213 if ( ret != null && ! ret . equals ( " " ) ) {
214 if ( d a t a U p l o a d C h e c k T r u e () ) {
215 int [] r = da t a M e th o d F r am e . table . g e tS e l e c te d R o ws () ;
216 int [] c = da t a M e th o d F r am e . table . g e t S e l e c t e d C o l u m n s () ;
217 String x ;
218 String cmd ;
219 String selMode = " " ;
220
221 // cell or col s e l e c t i o n
222 if ( c . length > 0 &&
223 ( d a ta M e t h od F r a m e . table . g e t C e l l S e l e c t i o n E n a b l e d () ||
224 d a ta M e t h od F r a m e . table . g e t C o l u m n S e l e c t i o n A l l o w e d () ) ) {
225 // col s e l e c t i o n
226 if ( d at a M e t ho d F r am e . table . g e t C o l u m n S e l e c t i o n A l l o w e d () &&
227 ! d a ta M e t h od F r a m e . table . g e t C e l l S e l e c t i o n E n a b l e d () ) {
228 x = d a t a M et h o d Fr a m e . dataSetName + " [ , " + ( c [0] + 1) + " ] " ;
229 selMode = " [ , " + ( c [0] + 1) + " ] " ;
230 for ( int j = 1; j < c . length ; j ++) {
231 x = x + " ~ " + d a t aM e t h od F r a m e . dataSetName + " [ , " + ( c [ j ] + 1) + " ] " ;
232 selMode = selMode + " ~ " + " [ , " + ( c [ j ] + 1) + " ] " ;
233 }
234 cmd = ret + " = " + x ;
235
236 // cell s e l e c t i o n
237 }
238 else {
239 // selMode = "[" + ( r [0]+1) + " ," + ( c [0]+1) + "]~[" + ( r [ r . length -1]+1) + " ," + ( c
[ c . length -1]+1) + "]";
240 x = "(";
241 selMode = " ( " ;
242 for ( int j = 0; j < r . length ; j ++) {
243 for ( int k = 0; k < c . length ; k ++) {
244 if ( k != 0) {
245 x = x + "~";
246 selMode = selMode + " ~ " ;
247 }
248 x = x + d a t a Me t h o d Fr a m e . dataSetName + " [ " + ( r [ j ] + 1) + " ," + ( c [ k ] + 1) + " ]
";
249 selMode = selMode + " [ " + ( r [ j ] + 1) + " ," + ( c [ k ] + 1) + " ] " ;
250 }
251 x = x + " ) |( " ;
252 selMode = selMode + " ) |( " ;
253 }
254 x = x . substring (0 , x . length () - 2) ;
255 selMode = selMode . substring (0 , selMode . length () - 2) ;
256 if ( selMode . length () > 62) {
257 selMode = selMode . substring (0 , 60) ;
258 selMode = selMode + " ... " ;
259 }
260 cmd = ret + " = " + x ;
261 }
262 }
263 else {
264 // all data
265 selMode = client . XOpt . XQCF015 ;
266 cmd = ret + " = " + d a t a M et h o d F ra m e . dataSetName ;
267 }
268
269 d a ta M e t h od F r a m e . getClient () . getXQServer () . sendQuantlet ( cmd ) ;
270
271 // update S e r v e r O b j e c t L i s t
272 if (! d a t aM e t h o dF r a m e . getClient () . s e r v e r O b j e c t L i s t M o d e l . contains ( ret ) ) {
273 d a t aM e t h o dF r a m e . getClient () . s e r v e r O b j e c t L i s t M o d e l . addElement ( ret ) ;
274 int size = d a t aM e t h o dF r a m e . getClient () . s e r v e r O b j e c t L i s t M o d e l . getSize () - 1;
275 d a t aM e t h o dF r a m e . getClient () . s e r v e r O b j e c t L i s t . e n s u r e I n d e x I s V i s i b l e ( size ) ;
276 }
277 String value = ret + " - " + client . XOpt . XQCF016 + " :\ n " ;
278 value = value + da t a M et h o d F ra m e . name + " \ n " ;
279 value = value + selMode + " \ n " ;
280 d a ta M e t h od F r a m e . getClient () . s e r v e r O b j e c t I n f o r m a t i o n . put ( ret , value ) ;
281
282 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . MESSAGE ,
166
B.9 XDataMethodAction.java
167
XQC Source Code
379 }
380 catch ( Exception eCopy ) {
381 System . out . println ( " Nothing selected to COPY ! " ) ;
382 }
383 }
384
385 if ( arg . equals ( " Paste " ) ) {
386 String rowString ;
387 String value ;
388 int startRow = ( d a t a M et h o d F ra m e . table . g et S e l e ct e d R o ws () ) [0];
389 int startCol = ( d a t a M et h o d F ra m e . table . g e t S e l e c t e d C o l u m n s () ) [0];
390 try {
391 String trString = ( String ) ( system . getContents ( this ) . g e t T ra n s f e rD a t a ( DataFlavor .
392 stringFlavor ) ) ;
393 S t ri n g T o ke n i z e r st1 = new S t r in g T o k en i z e r ( trString , " \ n " ) ;
394 for ( int i = 0; st1 . hasMoreTokens () ; i ++) {
395 rowString = st1 . nextToken () ;
396 S t r in g T o k en i z e r st2 = new S t r i ng T o k e ni z e r ( rowString , " \ t " ) ;
397
398 for ( int j = 0; st2 . hasMoreTokens () ; j ++) {
399 value = ( String ) st2 . nextToken () ;
400 if ( startRow + i < da t a M e th o d F r am e . table . getRowCount () &&
401 startCol + j < d a t a Me t h o d Fr a m e . table . ge tC olu mn Cou nt () ) {
402 d a t aM e t h o dF r a m e . table . setValueAt ( value , startRow + i , startCol + j ) ;
403 }
404 }
405 }
406 d a ta M e t h od F r a m e . table . repaint () ;
407 }
408 catch ( Exception exception ) {
409 exception . pr i n t S ta c k T r ac e () ;
410 }
411 }
412 if ( arg . equals ( " headerRow " ) ) {
413 int [] r = da t a M e th o d F r am e . table . g e tS e l e c te d R o w s () ;
414 if ( r . length != 0) {
415 d a ta M e t h od F r a m e . setColHeader ( r [0]) ;
416 }
417 }
418 if ( arg . equals ( " colHeader " ) ) {
419 int [] c = da t a M e th o d F r am e . table . g e t S e l e c t e d C o l u m n s () ;
420 if ( c . length != 0) {
421 d a ta M e t h od F r a m e . s e t S i n g l e C o l H e a d e r ( c [0]) ;
422 }
423 }
424 if ( arg . equals ( " deleteRow " ) ) {
425 int [] r = da t a M e th o d F r am e . table . g e tS e l e c te d R o w s () ;
426 if ( r . length != 0) {
427 d a ta M e t h od F r a m e . deleteRow ( r [0]) ;
428 }
429 }
430 if ( arg . equals ( " insertRow " ) ) {
431 int [] r = da t a M e th o d F r am e . table . g e tS e l e c te d R o w s () ;
432 if ( r . length != 0) {
433 d a ta M e t h od F r a m e . insertRow ( r [0]) ;
434 }
435 }
436 if ( arg . equals ( " addRow " ) ) {
437 d a ta M e t h od F r a m e . addRow () ;
438 }
439 if ( arg . equals ( " deleteCol " ) ) {
440 int [] c = da t a M e th o d F r am e . table . g e t S e l e c t e d C o l u m n s () ;
441 if ( c . length != 0) {
442 d a ta M e t h od F r a m e . deleteCol ( c [0]) ;
443 }
444 }
445 if ( arg . equals ( " addCol " ) ) {
446 d a ta M e t h od F r a m e . addCol () ;
447 }
448 if ( arg . equals ( " Tree " ) ) {
449 if ( client . XOpt . treeVector . size () < 1) {
450 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCF030 ) ;
451 }
452 else {
453 XDialog dialog = new XDialog () ;
454 dialog . s h o w R a d i o B u t t o n G r o u p ( client , client . XOpt . treeVector , client . XOpt . XQCF031 + " : " ) ;
455 String ret = dialog . ret ;
456 if ( ret != null ) {
457 X D a t a M e t h o d F r a m e T r e e newTreeModel = new X D a t a M e t h o d F r a m e T r e e ( client , ret ) ;
458 d a t aM e t h od F r a m e . se t N e wT r e e M od e l ( newTreeModel ) ;
459 d a t aM e t h od F r a m e . setTree ( new JTree ( newTreeModel . iniTreeModel () ) ) ;
460 }
461 }
462 }
463 }
464
465 private String tableToString ( String [][] data ) {
466 int [] i = d at a M e th o d F r am e . getJTableSize () ;
467 String temp = " " ;
468 boolean notEmpty = false ;
469 TableColumn tCol ;
470 int kk ;
471 for ( int j = 0; j < i [0]; j ++) {
472 for ( int k = 0; k < i [1]; k ++) {
473 // in case the cols have been moved - get the right column
474 tCol = d a ta M e t h od F r a m e . columnModel . getColumn ( k ) ;
168
B.9 XDataMethodAction.java
169
XQC Source Code
571
572 public void tableChanged ( T a b l eM o d e l Ev e n t e ) {
573 }
574
575 public void c o l u m n S e l e c t i o n C h a n g e d ( L i s t S e l e c t i o n E v e n t e ) {
576 }
577
578 public void c o l u m n M a r g i n C h a n g e d ( ChangeEvent e ) {
579 }
580
581 public void columnMoved ( T a b l e C o l u m n M o d e l E v e n t e ) {
582 int from = e . getFromIndex () ;
583 int to = e . getToIndex () ;
584
585 if ( from == to ) {
586 return ;
587 }
588 UPLOADED = false ;
589 }
590
591 public void columnRemoved ( T a b l e C o l u m n M o d e l E v e n t e ) {
592 }
593
594 public void columnAdded ( T a b l e C o l u m n M o d e l E v e n t e ) {
595 System . out . println ( " table changed " ) ;
596 }
597
598 // check whether the c o m p l e t e data - set is already u p l o a de d or not
599 protected boolean d a t a U p l o a d C h e c k T r u e () {
600 if (! UPLOADED ) {
601 if ( da t a M e th o d F r am e . getClient () . status == XQSListener . SERVER_READY ) {
602 doubleData = dataToDouble ( d a t aM e t h o dF r a m e . getTableModel () . getData () ) ;
603 if ( doubleData == null || doubleData . length == 0) {
604 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCF026 ) ;
605 return false ;
606 }
607 else {
608 doubleMatrix = new X Q C D o ub l e M a tr i x ( doubleData , da t a M e th o d F r am e . dataSetName ) ;
609 System . out . println ( " Uploading " + da t a M et h o d F ra m e . dataSetName ) ;
610 d a t aM e t h od F r a m e . getClient () . getXQServer () . p ut D o u b le M a t ri x ( doubleMatrix ) ;
611 // n e s s e s a r y to cut the server c o n n e c t i o n ?!
612 doubleMatrix = null ;
613 UPLOADED = true ;
614 return true ;
615 }
616 }
617 else if ( d at a M e t ho d F r a me . getClient () . status == XQSListener . SERVER_BUSY ) {
618 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCF018 ) ;
619 }
620 else {
621 if ( da t a M e th o d F r am e . getClient () . status == XQSListener . NOT_CONNECTED ) {
622 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCF019 ) ;
623 }
624 }
625 return false ;
626 }
627 return true ;
628 }
629
630 private double [][] dataToDouble ( String [][] data ) {
631 int [] i = d at a M e th o d F r am e . getJTableSize () ;
632 int tempN = 0;
633 int sizeN = 0;
634 int sizeM = 0;
635 boolean notEmpty = false ;
636 boolean N u m b e r F o r m a t E x c e p t i o n = false ;
637 boolean Exception = false ;
638
639 // get the real size of the table ( filled with data )
640 for ( int j = 0; j < i [0]; j ++) {
641 tempN = 0;
642 for ( int k = 0; k < i [1]; k ++) {
643 if ( data [ j ][ k ] != null ) {
644 if (! data [ j ][ k ]. equals ( " " ) ) {
645 tempN = k + 1;
646 notEmpty = true ;
647 }
648 }
649 }
650 if ( tempN > sizeN ) {
651 sizeN = tempN ;
652 }
653 if ( notEmpty ) {
654 sizeM = j + 1;
655 }
656 notEmpty = false ;
657 }
658
659 // extract the data - build the matrix
660 double [][] temp = new double [ sizeM ][ sizeN ];
661 TableColumn tCol ;
662 int kk ;
663 for ( int j = 0; j < sizeM ; j ++) {
664 for ( int k = 0; k < sizeN ; k ++) {
665 // in case the cols have been moved - get the right column
666 tCol = d a ta M e t h od F r a m e . columnModel . getColumn ( k ) ;
170
B.9 XDataMethodAction.java
171
XQC Source Code
172
B.10 XDataTableModel.java
B.10 XDataTableModel.java
1 package xqc ;
2
3 import java . util .*;
4 import javax . swing . table .*;
5
6 /* *
7 * <p > X D a t a T a b l e M o d e l - g e n e r a t e s the spread sheet </ p >
8 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
9 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
10 * @ v e r s i o n March 2004
11 */
12 class X D at a T a b le M o d e l
13 extends A b s t r a c t T a b l e M o d e l {
14 private int rows ;
15 private int cols ;
16 private String [][] data ;
17 private X D a t a M e t h o d A c t i o n aL ; // to upload value changes
18
19 protected X Da t a T a bl e M o de l ( int rows , int cols , String [][] data , X D a t a M e t h o d A c t i o n aL ) {
20 this . rows = rows ;
21 this . cols = cols ;
22 this . data = data ;
23 this . aL = aL ;
24 }
25
26 public int getRowCount () {
27 return rows ;
28 }
29
30 public int g etC ol umn Co unt () {
31 return cols ;
32 }
33
34 public String [][] getData () {
35 return data ;
36 }
37
38 public boolean i sCe llE di tab le ( int rowIndex , int colIndex ) {
39 return rowIndex < rows && colIndex < cols ;
40 }
41
42 public Object getValueAt ( int rowIndex , int colIndex ) {
43 String value = data [ rowIndex ][ colIndex ];
44 return value == null ? " " : value ;
45 }
46
47 public void setValueAt ( Object aValue , int rowIndex , int colIndex ) {
48 String value = ( String ) aValue ;
49 data [ rowIndex ][ colIndex ] = value ;
50 if ( aL . getUPLOADED () ) {
51 try {
52 double temp = Double . valueOf ( value ) . doubleValue () ;
53 }
54 catch ( Exception e ) {
55 System . out . println ( " Wrong data format ! " ) ;
56 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( aL . g e t D a t a M e t h o d F r a m e () . getClient () ,
57 XDialog . MESSAGE , aL . g e t D a t a M e t h o d F r a m e () . getClient () . XOpt . XQCS001 ) ;
58 value = " 0 " ;
59 }
60 String cmd = aL . g e t D a t a M e t h o d F r a m e () . dataSetName + " [ " + ( rowIndex + 1) + " ," + ( colIndex +
1) +
61 " ] " + " = " + value ;
62 System . out . println ( cmd ) ;
63 aL . g e t D a t a M e t h o d F r a m e () . getClient () . getXQServer () . sendQuantlet ( cmd ) ;
64 }
65 }
66
67 }
173
XQC Source Code
B.11 XDataMethodFrameTree.java
1 package xqc ;
2
3 import javax . swing .*;
4 import javax . swing . tree .*;
5 import java . io .*;
6 import java . util .*;
7 import java . net .*;
8
9 /* *
10 * <p > X D a t a M e t h o d F r a m e T r e e - g e n e r a t e s the method tree </ p >
11 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
12 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
13 * @ v e r s i o n March 2004
14 */
15 class X D a t a M e t h o d F r a m e T r e e
16 extends Properties {
17 protected XClient client = null ;
18 private String optFileName ;
19 private D e f a u l t M u t a b l e T r e e N o d e root ;
20 private D e f a u l t M u t a b l e T r e e N o d e [] node ;
21 private D e f a u l t M u t a b l e T r e e N o d e [] child ;
22 private int nodeNo = 1;
23 private int childNo = 1;
24 private String [] nodeName ;
25 private String [] childName ;
26 private String [][] noOfChildren ;
27 private String methodPath ;
28 private String [] m e t h o d D e s c r i p t i o n ;
29
30 protected X D a t a M e t h o d F r a m e T r e e ( XClient client , String optFileName ) {
31 this . client = client ;
32 this . optFileName = optFileName ;
33 }
34
35 protected D e f a u l t M u t a b l e T r e e N o d e iniTreeModel () {
36 root = new D e f a u l t M u t a b l e T r e e N o d e ( " XQC " ) ;
37 node = new D e f a u l t M u t a b l e T r e e N o d e [4];
38 child = new D e f a u l t M u t a b l e T r e e N o d e [4];
39 nodeName = new String [4];
40 childName = new String [4];
41 m e t h o d D e s c r i p t i o n = new String [2];
42
43 InputStream fin = null ;
44 if (! XClient . ISAPPLET ) {
45 try {
46 fin = new Fi l e I n pu t S t re a m ( optFileName ) ;
47 }
48 catch ( F i l e N o t F o u n d E x c e p t i o n e ) {
49 System . out . println ( " optionfile " + optFileName + " not found " ) ;
50 }
51 }
52 else {
53 try {
54 optFileName = client . XOpt . XQCROOT + optFileName ;
55 if (! optFileName . startsWith ( " http " ) ) {
56 optFileName = " file :/// " + optFileName ;
57 }
58 URL iniurl = new URL ( optFileName ) ;
59 URLConnection inicon = iniurl . ope nCo nn ect io n () ;
60 fin = inicon . g et Inp ut Str ea m () ;
61 }
62 catch ( M a l f o r m e d U R L E x c e p t i o n e ) {
63 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR ,
64 optFileName + " - " + client . XOpt . XQCE001 ) ;
65 }
66 catch ( IOException e ) {
67 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR ,
68 optFileName + " - " + client . XOpt . XQCE002 ) ;
69 }
70 }
71
72 try {
73 if ( fin != null ) {
74 load ( fin ) ;
75 int i = 200; // max . of c h i l d r e n = methods
76 noOfChildren = new String [ i ][2];
77 int j = 0;
78
79 // begin - m e t h o d T r e e
80
81 // first level
82 int a = 1;
83 do {
84 nodeName [0] = getProperty ( " Node_ " + String . valueOf ( a ) , " " ) ;
85 childName [0] = getProperty ( " Child_ " + String . valueOf ( a ) , " " ) ;
86
87 if (! nodeName [0]. equals ( " " ) ) {
88 node [0] = new D e f a u l t M u t a b l e T r e e N o d e ( nodeName [0]) ;
89 root . add ( node [0]) ;
90 }
91 if (! childName [0]. equals ( " " ) ) {
92 m e t h o d D e s c r i p t i o n = c h i l d M e t h o d D e s c r i p t i o n ( childName [0]) ;
174
B.11 XDataMethodFrameTree.java
175
XQC Source Code
184 // end - m e t h o d T r e e
185
186 }
187 else {
188 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR ,
189 optFileName + " - " + client . XOpt . XQCE003 ) ;
190 }
191 }
192 catch ( java . lang . I n d e x O u t O f B o u n d s E x c e p t i o n e1 ) {
193 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , client . XOpt . XQCE004 ) ;
194 }
195 catch ( java . lang . Throwable e2 ) {
196 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR ,
197 optFileName + " - " + client . XOpt . XQCE005 ) ;
198 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( client , XDialog . ERROR , e2 . toString () ) ;
199 }
200
201 return root ;
202 }
203
204 protected String getMethodPath () {
205 return methodPath ;
206 }
207
208 protected String [][] g et N o O f Ch i l d r en () {
209 return noOfChildren ;
210 }
211
212 private String [] c h i l d M e t h o d D e s c r i p t i o n ( String rawString ) {
213 String [] temp = new String [2];
214 String str = " " ;
215 int i = 0;
216 while (! str . equals ( " | " ) && i < rawString . length () - 1) {
217 str = rawString . substring (i , i + 1) ;
218 i = i + 1;
219 }
220 if ( str . equals ( " | " ) ) {
221 temp [0] = rawString . substring (i , rawString . length () ) ;
222 temp [1] = rawString . substring (0 , i - 1) ;
223 }
224 else {
225 temp [0] = rawString ;
226 temp [1] = rawString ;
227 }
228 return temp ;
229 }
230
231 }
176
B.12 XDisplayFrame.java
B.12 XDisplayFrame.java
1 package xqc ;
2
3 import javax . swing .*;
4 import com . mdcrypt . mdcrypt .*;
5 import javax . swing . event .*;
6 import java . awt .*;
7 import java . awt . event .*;
8
9 /* *
10 * <p > X D i s p l a y F r a m e - holds a XDisplay </ p >
11 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
12 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
13 * @ v e r s i o n March 2004
14 */
15 class XDisplayFrame
16 extends JI nte rn alF ra me
17 implements InternalFrameListener , A ct ion Li ste ner {
18 protected XClient client ;
19 private XDisplay disp ;
20 private XSetGOpt gOpt ;
21 private int id ;
22 private int rows ;
23 private int cols ;
24 private int h = XClient . displayHeight ;
25 private int w = XClient . displayWidth ;
26 private int dispPos = XClient . dispPos ;
27
28 protected XDisplayFrame ( int id , int rows , int cols , int dispPos , XClient client ) {
29 super ( " XQC - " + client . XOpt . XQCH001 ) ;
30 this . client = client ;
31 this . a d d I n t e r n a l F r a m e L i s t e n e r ( this ) ;
32 this . id = id ;
33 this . rows = rows ;
34 this . cols = cols ;
35 initialize () ;
36 }
37
38 private void initialize () {
39 try {
40 if ( dispPos == 10) {
41 XClient . dispPos = 0;
42 }
43 int x = dispPos * 20;
44 h = h + 20; // add . space for the print button
45 setBounds (x , x , w , h ) ;
46 setFrameIcon ( new ImageIcon ( getClass () . getResource ( " / xqc / xqc . gif " ) ) ) ;
47 setName ( " DisplayFrame " ) ;
48 se tIc on ifi ab le ( true ) ;
49 setClosable ( true ) ;
50 setSize (w , h ) ;
51 s e t P r e f e r r e d S i z e ( new Dimension (w , h ) ) ;
52 se tMa xi miz ab le ( true ) ;
53 setResizable ( true ) ;
54 disp = new XDisplay ( id , rows , cols , this ) ;
55 // add the X D i s p l a y to the L i s t e n e r L i s t
56 client . getXQServer () . addListener ( disp ) ;
57
58 ImageIcon printicon = new ImageIcon ( getClass () . getResource ( " / xqc / print . gif " ) ) ;
59 ImageIcon printicon1 = new ImageIcon ( getClass () . getResource ( " / xqc / print - on . gif " ) ) ;
60 XButton print = new XButton ( printicon , printicon1 ) ;
61 print . s et Too lT ipT ext ( client . XOpt . XQCH002 + " ... " ) ;
62 print . s e t A c t i o n C o m m a n d ( " Print display ... " ) ;
63 print . a d d A c t i o n L i s t e n e r ( this ) ;
64
65 JPanel menu = new JPanel () ;
66 menu . setLayout ( new FlowLayout ( FlowLayout . LEFT ) ) ;
67 menu . setBackground ( new Color (222 , 222 , 222) ) ;
68 menu . add ( print ) ;
69
70 // create the C o n t e n t P a n e
71 JPanel contentPane = new JPanel () ;
72 contentPane . setLayout ( new BorderLayout () ) ;
73 contentPane . add ( menu , " North " ) ;
74 contentPane . add ( disp , " Center " ) ;
75
76 se tCo nt ent Pa ne ( contentPane ) ;
77
78 }
79 catch ( java . lang . Throwable ivjExc ) {
80 h a n dl e E x c ep t i o n ( ivjExc ) ;
81 }
82 System . out . println ( " ID : " + id ) ;
83 System . out . println ( " rows : " + rows ) ;
84 System . out . println ( " cols : " + cols ) ;
85 }
86
87 protected void h a n d l e S e t G O p t _ s e t S i z e ( int w , int h ) {
88 setSize (w , h ) ;
89 }
90
91 protected XDisplay getDisp () {
92 return disp ;
177
XQC Source Code
93 }
94
95 public void a c t i on P e r fo r m e d ( ActionEvent e ) {
96 String arg = e . g e t A c t i o n C o m m a n d () ;
97
98 if ( arg . equals ( " Print display ... " ) ) {
99 disp . printDisplay () ;
100 }
101 }
102
103 public void i n t e r n a l F r a m e C l o s i n g ( I n t e r n a l F r a m e E v e n t e ) {
104 XClient . dispPos = XClient . dispPos - 1;
105 }
106
107 public void i n t e r n a l F r a m e C l o s e d ( I n t e r n a l F r a m e E v e n t e ) {
108 }
109
110 public void i n t e r n a l F r a m e O p e n e d ( I n t e r n a l F r a m e E v e n t e ) {
111 }
112
113 public void i n t e r n a l F r a m e I c o n i f i e d ( I n t e r n a l F r a m e E v e n t e ) {
114 }
115
116 public void i n t e r n a l F r a m e D e i c o n i f i e d ( I n t e r n a l F r a m e E v e n t e ) {
117 this . toFront () ;
118 }
119
120 public void i n t e r n a l F r a m e A c t i v a t e d ( I n t e r n a l F r a m e E v e n t e ) {
121 }
122
123 public void i n t e r n a l F r a m e D e a c t i v a t e d ( I n t e r n a l F r a m e E v e n t e ) {
124 }
125
126 private void h an d l e E xc e p t i on ( Throwable exception ) {
127 System . out . println ( " - - - - - - - - - UNCAUGHT EXCEPTION - - - - - - - - - " ) ;
128 exception . pr i n t S ta c k T r ac e ( System . out ) ;
129 }
130
131 }
178
B.13 XDisplay.java
B.13 XDisplay.java
1 package xqc ;
2
3 import javax . swing .*;
4 import com . mdcrypt . mdcrypt .*;
5 import java . awt .*;
6 import java . awt . print .*;
7
8 /* *
9 * <p > X D i s p l a y - JPanel inside the XDisplayFrame , holds the single plots </ p >
10 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
11 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
12 * @ v e r s i o n March 2004
13 */
14 class XDisplay
15 extends JPanel
16 implements XQSListener , Printable {
17 protected XDisplayFrame frame = null ;
18 private XSetGOpt gOpt = null ;
19 private XPlot plot = null ;
20 private X Q S G r a p h i c s O b j e c t obj = null ;
21 private int id ;
22 private int rows , r ;
23 private int cols , c ;
24 // dummy is needed for the print routine , o t h e r w i s e it runs it twice
25 private int dummy = 1;
26 protected boolean i s S t a n d A l o n e P l o t = true ;
27
28 // C o n s t r u c t o r for e x t e r n a l use
29 public XDisplay ( int id , int rows , int cols ) {
30 super () ;
31 this . id = id ;
32 this . rows = rows ;
33 this . cols = cols ;
34 i s S t a n d A l o n e P l o t = true ;
35 initialize () ;
36 }
37
38 // C o n s t r u c t o r for use within the XQC
39 public XDisplay ( int id , int rows , int cols , XDisplayFrame frame ) {
40 super () ;
41 this . frame = frame ;
42 this . id = id ;
43 this . rows = rows ;
44 this . cols = cols ;
45 i s S t a n d A l o n e P l o t = false ;
46 initialize () ;
47 }
48
49 private void initialize () {
50 try {
51 setName ( " Display " ) ;
52 setLayout ( new java . awt . GridLayout ( rows , cols , 2 , 2) ) ;
53 JPanel p ;
54 for ( int i = 0; i < rows * cols ; i ++) {
55 int r = ( int ) Math . ceil ( ( ( double ) i + 1) / ( double ) cols ) ;
56 int c = ( i + 1) - ( ( r - 1) * cols ) ;
57 p = new JPanel () ;
58 p . setBackground ( new java . awt . Color (255 , 255 , 255) ) ;
59 p . add ( new JLabel ( frame . client . XOpt . XQCI001 + " ( " + r + " , " + c + " ) " ) , " Center " ) ;
60 add ( p ) ;
61 }
62 }
63 catch ( java . lang . Throwable e ) {
64 h a n dl e E x c ep t i o n ( e ) ;
65 }
66 }
67
68 private void setPlot ( X Q S G r a p h i c s O b j e c t obj ) {
69 this . obj = obj ;
70 r = obj . getRow () ;
71 c = obj . getCol () ;
72 if ( r > rows ) {
73 System . out . println ( " row to large " ) ;
74 }
75 if ( c > cols ) {
76 System . out . println ( " col to large " ) ;
77 }
78 int pos = ( r - 1) * cols + ( c - 1) ;
79 plot = new XPlot ( obj , this ) ;
80 System . out . println ( " new XPlot for Position " + ( pos + 1) + " generated " ) ;
81 remove ( pos ) ;
82 add ( plot , pos ) ;
83 repaint () ;
84 updateUI () ;
85 }
86
87 protected XPlot getPlot ( int r , int c ) {
88 try {
89 if ( r > rows ) {
90 System . out . println ( " row to large " ) ;
91 }
92 if ( c > cols ) {
179
XQC Source Code
180
B.13 XDisplay.java
189 }
190 }
191 else {
192 if ( obj . getDisplayID () == this . getId () ) {
193 this . setPlot ( obj ) ;
194 this . setVisible ( true ) ;
195 }
196 }
197 }
198 // handle A D D _ D A TA
199 if ( x . getType () == XQSObject . ADD_DATA ) {
200 X Q S G r a p h i c s O b j e c t obj = ( X Q S G r a p h i c s O b j e c t ) x ;
201 if (! i s S t a n d A l o n e P l o t ) {
202 if ( obj . getDisplayID () == this . getId () && ! frame . isClosed () ) {
203 X Q S G r a p h i c s O b j e c t oldObj = this . g e t X Q S G r a p h i c s O b j e c t () ;
204 }
205 else if ( obj . getDisplayID () == this . getId () && frame . isClosed () ) {
206 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( frame . client , XDialog . ERROR ,
207 frame . client . XOpt . XQCI002 ) ;
208 System . out . println ( " Display not found ! " ) ;
209 }
210 }
211 else {
212 if ( obj . getDisplayID () == this . getId () ) {
213 X Q S G r a p h i c s O b j e c t oldObj = this . g e t X Q S G r a p h i c s O b j e c t () ;
214 }
215 }
216 }
217 // handle SETGOPT
218 if ( x . getType () == XQSObject . SETGOPT ) {
219 X Q S S e t G O p t O b j e c t obj = ( X Q S S e t G O p t O b j e c t ) x ;
220 if ( obj . getId () == this . getId () ) {
221 if ( gOpt == null ) {
222 if (! i s S t a n d A l o n e P l o t ) {
223 gOpt = new XSetGOpt ( this , frame ) ;
224 }
225 else {
226 gOpt = new XSetGOpt ( this ) ;
227 }
228 }
229 gOpt . setOptions ( obj ) ;
230 }
231 }
232 return null ;
233 }
234
235 public void s e r v e r S t a t u s C h a n g e d ( int i ) {
236 }
237
238 public void h a n d l e M d C r y p t E x c e p t i o n ( X Q S S t a t u s M e s s a g e xqsSTM ) {
239 }
240
241 private void h an d l e E xc e p t i on ( java . lang . Throwable exception ) {
242 System . out . println ( " - - - - - - - - - UNCAUGHT EXCEPTION - - - - - - - - - " ) ;
243 exception . pr i n t S ta c k T r ac e ( System . out ) ;
244 }
245
246 }
181
XQC Source Code
B.14 XPlot.java
1 package xqc ;
2
3 import javax . swing .*;
4 import com . mdcrypt . mdcrypt .*;
5 import java . awt .*;
6 import java . awt . geom .*;
7 import java . awt . print .*;
8 import java . util .*;
9 import java . lang .*;
10
11 /* *
12 * <p > XPlot - a single plot within a display </ p >
13 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
14 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
15 * @ v e r s i on March 2004
16 */
17 class XPlot
18 extends JPanel
19 implements Printable {
20 private int width = 0;
21 private int height = 0;
22 protected XDisplay disp = null ;
23 private XPlotAction aL = null ;
24 private X Q S G r a p h i c s O b j e c t obj = null ;
25 private XQSDataObject dp = null ;
26 protected int border = 1; // border for p ri n t i n g
27 protected String title = " " ;
28 protected String xLabel ;
29 protected String yLabel ;
30 private double [][] x ;
31 private double [][] y ;
32 private double [][] z ;
33 private double [][] xyz = {{0.5 , 0 , 0} , {0 , 0.5 , 0} , {0 , 0 , 0.5}};
34 private double [][] xyzTxt = {{0.6 , 0 , 0} , {0 , 0.6 , 0} , {0 , 0 , 0.6}};
35 private double xMin , xMax ;
36 private double yMin , yMax ;
37 private double zMin , zMax ;
38 private double xFactor ;
39 private double yFactor ;
40 private double zFactor ;
41 private int dim = 0;
42 protected int type ;
43 private int ndp ;
44 private Polygon pol ;
45 protected Vector toolTip = new Vector () ; // needed for toolTip
46 private double [][] xOrg ; // needed for toolTip
47 private double [][] yOrg ; // needed for toolTip
48 private double [][] zOrg ; // needed for toolTip
49 private String ttText = null ; // needed for toolTip
50
51 // d e f i n i t i o n of the r o t a t i o n m a t r i c e s
52 private double r = Math . PI / 72;
53 private double [][] rMat = {{1 , 0 , 0} , {0 , 1 , 0} , {0 , 0 , 1}};
54 private double [][] rMatXZ ;
55 private double [][] rMatZX ;
56 private double [][] rMatYZ ;
57 private double [][] rMatZY ;
58
59 private double [] xRot = null ;
60 private double [] yRot = null ;
61 private double [] zRot = null ;
62
63 private Haxis haxisS , haxisN ;
64 private Vaxis vaxisW , vaxisE ;
65 private boolean xAxis = XClient . AXIS ;
66 private boolean yAxis = XClient . AXIS ;
67
68 // paint c o n s t u r c t o r s
69 private Ellipse2D ellipse2D = new Ellipse2D . Double () ;
70 private Rectangle2D rectangle2D = new Rectangle2D . Double () ;
71 private GeneralPath triangle = null ;
72 private Line2D line2D = new Line2D . Double () ;
73 private GeneralPath rhombus = null ;
74
75 protected XPlot ( X Q S G r a p h i c s O b j e c t obj , XDisplay disp ) {
76 super () ;
77 System . out . println ( " generating new XPlot " ) ;
78 setBackground ( Color . white ) ;
79 this . obj = obj ;
80 this . disp = disp ;
81
82 xLabel = "x - " + disp . frame . client . XOpt . XQCJ001 ;
83 yLabel = "y - " + disp . frame . client . XOpt . XQCJ001 ;
84
85 haxisS = new Haxis (0 , 0, 0, 0, 0, 0) ;
86 haxisN = new Haxis (0 , 0, 0, 0, 0, 0) ;
87 vaxisW = new Vaxis (0 , 0, 0, 0, 0, 0) ;
88 vaxisE = new Vaxis (0 , 0, 0, 0, 0, 0) ;
89
90 // get type and d i m e n s i o n of the data
91 type = ( ( XQSDataObject ) obj . getDataObject (0) ) . getDataType () ;
92 dim = obj . getDim () ;
182
B.14 XPlot.java
183
XQC Source Code
184
B.14 XPlot.java
185
XQC Source Code
381 if ( strCut ) {
382 g2D . drawString ( " ... " , xoff - 25 , yoff - 10 + m . getHeight () * ( i + 1) ) ;
383 }
384 g2D . s e t R e n d e r i n g H i n t ( R end er ing Hi nts . KEY_ANTIALIASING , Re nde rin gH int s . V A L U E _ A N T I A L I A S _ O N ) ;
385 return ;
386 }
387
388 // handle graphic output
389 if ( type == 1) {
390
391 // handle 2 D g r a p h i c s
392 if ( dim == 2) {
393 // c a l c u l a t e the factors
394 xFactor = ( ( double ) width ) / ( xMax - xMin ) ;
395 yFactor = ( ( double ) height ) / ( yMax - yMin ) ;
396 }
397
398 // handle 3 D g r a p hi c s
399 if ( dim == 3) {
400 // call the r o t a t i o n method
401 rotate (k , size ) ;
402 }
403
404 int xt = 0;
405 int xtOld = 0;
406 int yt = 0;
407 int ytOld = 0;
408
409 // start p a i n t i n g the data points
410 for ( int i = 0; i < dp . ge t N u m be r O f R ow s () ; i ++) {
411
412 if ( dim == 2) {
413 xt = ( int ) ( ( x [ k ][ i ] - xMin ) * xFactor ) ;
414 yt = height - ( int ) ( ( y [ k ][ i ] - yMin ) * yFactor ) ;
415 }
416 if ( dim == 3) {
417 xt = ( int ) ( xRot [ i ] + width / 2) ;
418 yt = height - ( int ) ( yRot [ i ] + height / 2) ;
419 }
420
421 // get the color , look and size of the d a t a p o i n t
422 int pc = ( ( XQSDataObject ) obj . getDataObject ( k ) ) . getCorgData () [ i ];
423 Color pColor = new Color ( ( int ) (0 xffffff00 & pc ) >> 8) ;
424 int pLook = ( int ) (0 x000000f0 & pc ) >> 4;
425 s1 = ( int ) (0 x0000000f & pc ) ;
426 // Color pColor = dp . g e t P o i n t C o l o r ( i ) ;
427 // int pLook = dp . g e t P o i n t P o l y g o n ( i ) ;
428 // s1 = dp . g e t P o i n t S i z e ( i ) ;
429 s2 = s1 / 2; // 1/2 of the size ( int )
430 g2D . setColor ( pColor ) ;
431
432 // i n i t i a l i z e the a p p e a r a n c e of lines
433 g2D . setStroke ( new BasicStroke (1 , BasicStroke . CAP_BUTT , BasicStroke . JOIN_MITER ) ) ;
434
435 switch ( pLook ) {
436 case 0:
437 break ;
438 case 1: // point
439 ellipse2D . setFrame ( xt - 1 , yt - 1 , 2 , 2) ;
440 g2D . fill ( ellipse2D ) ;
441 pol = new Polygon () ;
442 pol . addPoint ( xt + xoff - 1 , yt + yoff - 1) ;
443 pol . addPoint ( xt + xoff + 1 , yt + yoff - 1) ;
444 pol . addPoint ( xt + xoff + 1 , yt + yoff + 1) ;
445 pol . addPoint ( xt + xoff - 1 , yt + yoff + 1) ;
446 toolTip . addElement ( pol ) ;
447 break ;
448 case 2: // r e c t a n g l e
449 rectangle2D . setFrame ( xt - s2 , yt - s2 , s1 , s1 ) ;
450 g2D . draw ( rectangle2D ) ;
451 pol = new Polygon () ;
452 pol . addPoint ( xt + xoff - s2 , yt + yoff - s2 ) ;
453 pol . addPoint ( xt + xoff + s2 , yt + yoff - s2 ) ;
454 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
455 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
456 toolTip . addElement ( pol ) ;
457 break ;
458 case 3: // circle
459 ellipse2D . setFrame ( xt - s2 , yt - s2 , s1 , s1 ) ;
460 g2D . draw ( ellipse2D ) ;
461 pol = new Polygon () ;
462 pol . addPoint ( xt + xoff - s2 , yt + yoff - s2 ) ;
463 pol . addPoint ( xt + xoff + s2 , yt + yoff - s2 ) ;
464 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
465 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
466 toolTip . addElement ( pol ) ;
467 break ;
468 case 4: // t r i a n g l e
469 int xtr [] = {
470 xt - s2 , xt , xt + s2 };
471 int ytr [] = {
472 yt + s2 , yt - s2 , yt + s2 };
473 triangle = new GeneralPath ( GeneralPath . WIND_EVEN_ODD , xtr . length ) ;
474 triangle . moveTo ( xtr [0] , ytr [0]) ;
475 for ( int l = 1; l < xtr . length ; l ++) {
476 triangle . lineTo ( xtr [ l ] , ytr [ l ]) ;
186
B.14 XPlot.java
477 }
478 triangle . closePath () ;
479 g2D . draw ( triangle ) ;
480 pol = new Polygon () ;
481 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
482 pol . addPoint ( xt + xoff , yt + yoff - s2 ) ;
483 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
484 toolTip . addElement ( pol ) ;
485 break ;
486 case 5: // x - symbol
487 line2D . setLine ( xt - s2 , yt - s2 , xt + s2 , yt + s2 ) ;
488 g2D . draw ( line2D ) ;
489 line2D . setLine ( xt - s2 , yt + s2 , xt + s2 , yt - s2 ) ;
490 g2D . draw ( line2D ) ;
491 pol = new Polygon () ;
492 pol . addPoint ( xt + xoff - s2 , yt + yoff - s2 ) ;
493 pol . addPoint ( xt + xoff + s2 , yt + yoff - s2 ) ;
494 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
495 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
496 toolTip . addElement ( pol ) ;
497 break ;
498 case 6: // rhombus
499 int xrh [] = {
500 xt - s2 , xt , xt + s2 , xt };
501 int yrh [] = {
502 yt , yt - s2 , yt , yt + s2 };
503 rhombus = new GeneralPath ( GeneralPath . WIND_EVEN_ODD , xrh . length ) ;
504 rhombus . moveTo ( xrh [0] , yrh [0]) ;
505 for ( int l = 1; l < xrh . length ; l ++) {
506 rhombus . lineTo ( xrh [ l ] , yrh [ l ]) ;
507 }
508 rhombus . closePath () ;
509 g2D . draw ( rhombus ) ;
510 pol = new Polygon () ;
511 pol . addPoint ( xt + xoff - s2 , yt + yoff ) ;
512 pol . addPoint ( xt + xoff , yt + yoff - s2 ) ;
513 pol . addPoint ( xt + xoff + s2 , yt + yoff ) ;
514 pol . addPoint ( xt + xoff , yt + yoff + s2 ) ;
515 toolTip . addElement ( pol ) ;
516 break ;
517 case 7: // filled r e c t a n g l e
518 rectangle2D . setFrame ( xt - s2 , yt - s2 , s1 , s1 ) ;
519 g2D . fill ( rectangle2D ) ;
520 pol = new Polygon () ;
521 pol . addPoint ( xt + xoff - s2 , yt + yoff - s2 ) ;
522 pol . addPoint ( xt + xoff + s2 , yt + yoff - s2 ) ;
523 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
524 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
525 toolTip . addElement ( pol ) ;
526 break ;
527 case 8: // filled circle
528 ellipse2D . setFrame ( xt - s2 , yt - s2 , s1 , s1 ) ;
529 g2D . fill ( ellipse2D ) ;
530 pol = new Polygon () ;
531 pol . addPoint ( xt + xoff - s2 , yt + yoff - s2 ) ;
532 pol . addPoint ( xt + xoff + s2 , yt + yoff - s2 ) ;
533 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
534 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
535 toolTip . addElement ( pol ) ;
536 break ;
537 case 9: // filled rhombus
538 int xfh [] = {
539 xt - s2 , xt , xt + s2 , xt };
540 int yfh [] = {
541 yt , yt - s2 , yt , yt + s2 };
542 rhombus = new GeneralPath ( GeneralPath . WIND_EVEN_ODD , xfh . length ) ;
543 rhombus . moveTo ( xfh [0] , yfh [0]) ;
544 for ( int l = 1; l < xfh . length ; l ++) {
545 rhombus . lineTo ( xfh [ l ] , yfh [ l ]) ;
546 }
547 rhombus . closePath () ;
548 g2D . fill ( rhombus ) ;
549 pol = new Polygon () ;
550 pol . addPoint ( xt + xoff - s2 , yt + yoff ) ;
551 pol . addPoint ( xt + xoff , yt + yoff - s2 ) ;
552 pol . addPoint ( xt + xoff + s2 , yt + yoff ) ;
553 pol . addPoint ( xt + xoff , yt + yoff + s2 ) ;
554 toolTip . addElement ( pol ) ;
555 break ;
556 case 10: // filled t r i a n g l e
557 int xft [] = {
558 xt - s2 , xt , xt + s2 };
559 int yft [] = {
560 yt + s2 , yt - s2 , yt + s2 };
561 triangle = new GeneralPath ( GeneralPath . WIND_EVEN_ODD , xft . length ) ;
562 triangle . moveTo ( xft [0] , yft [0]) ;
563 for ( int l = 1; l < xft . length ; l ++) {
564 triangle . lineTo ( xft [ l ] , yft [ l ]) ;
565 }
566 triangle . closePath () ;
567 g2D . fill ( triangle ) ;
568 pol = new Polygon () ;
569 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
570 pol . addPoint ( xt + xoff , yt + yoff - s2 ) ;
571 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
572 toolTip . addElement ( pol ) ;
187
XQC Source Code
573 break ;
574 case 11: // + - symbol
575 line2D . setLine ( xt - s2 , yt , xt + s2 , yt ) ;
576 g2D . draw ( line2D ) ;
577 line2D . setLine ( xt , yt + s2 , xt , yt - s2 ) ;
578 g2D . draw ( line2D ) ;
579 pol = new Polygon () ;
580 pol . addPoint ( xt + xoff - s2 , yt + yoff - s2 ) ;
581 pol . addPoint ( xt + xoff + s2 , yt + yoff - s2 ) ;
582 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
583 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
584 toolTip . addElement ( pol ) ;
585 break ;
586 case 12: // star - symbol
587 line2D . setLine ( xt - s2 , yt , xt + s2 , yt ) ;
588 g2D . draw ( line2D ) ;
589 line2D . setLine ( xt , yt + s2 , xt , yt - s2 ) ;
590 g2D . draw ( line2D ) ;
591 line2D . setLine ( xt - s2 * 0.75 , yt - s2 * 0.75 , xt + s2 * 0.75 , yt + s2 * 0.75) ;
592 g2D . draw ( line2D ) ;
593 line2D . setLine ( xt - s2 * 0.75 , yt + s2 * 0.75 , xt + s2 * 0.75 , yt - s2 * 0.75) ;
594 g2D . draw ( line2D ) ;
595 pol = new Polygon () ;
596 pol . addPoint ( xt + xoff - s2 , yt + yoff - s2 ) ;
597 pol . addPoint ( xt + xoff + s2 , yt + yoff - s2 ) ;
598 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
599 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
600 toolTip . addElement ( pol ) ;
601 break ;
602 case 13: // rectangle - grid - symbol
603 rectangle2D . setFrame ( xt - s2 , yt - s2 , s1 , s1 ) ;
604 g2D . draw ( rectangle2D ) ;
605 line2D . setLine ( xt - s2 , yt , xt + s2 , yt ) ;
606 g2D . draw ( line2D ) ;
607 line2D . setLine ( xt , yt + s2 , xt , yt - s2 ) ;
608 g2D . draw ( line2D ) ;
609 pol = new Polygon () ;
610 pol . addPoint ( xt + xoff - s2 , yt + yoff - s2 ) ;
611 pol . addPoint ( xt + xoff + s2 , yt + yoff - s2 ) ;
612 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
613 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
614 toolTip . addElement ( pol ) ;
615 break ;
616 case 14: // rhombus - grid - symbol
617 line2D . setLine ( xt - s2 , yt , xt + s2 , yt ) ;
618 g2D . draw ( line2D ) ;
619 line2D . setLine ( xt , yt + s2 , xt , yt - s2 ) ;
620 g2D . draw ( line2D ) ;
621 int xrg [] = {
622 xt - s2 , xt , xt + s2 , xt };
623 int yrg [] = {
624 yt , yt - s2 , yt , yt + s2 };
625 rhombus = new GeneralPath ( GeneralPath . WIND_EVEN_ODD , xrg . length ) ;
626 rhombus . moveTo ( xrg [0] , yrg [0]) ;
627 for ( int l = 1; l < xrg . length ; l ++) {
628 rhombus . lineTo ( xrg [ l ] , yrg [ l ]) ;
629 }
630 rhombus . closePath () ;
631 g2D . draw ( rhombus ) ;
632 pol = new Polygon () ;
633 pol . addPoint ( xt + xoff - s2 , yt + yoff ) ;
634 pol . addPoint ( xt + xoff , yt + yoff - s2 ) ;
635 pol . addPoint ( xt + xoff + s2 , yt + yoff ) ;
636 pol . addPoint ( xt + xoff , yt + yoff + s2 ) ;
637 toolTip . addElement ( pol ) ;
638 break ;
639 default :
640 ellipse2D . setFrame ( xt - s2 , yt - s2 , s1 , s1 ) ;
641 g2D . draw ( ellipse2D ) ;
642 pol = new Polygon () ;
643 pol . addPoint ( xt + xoff - s2 , yt + yoff - s2 ) ;
644 pol . addPoint ( xt + xoff + s2 , yt + yoff - s2 ) ;
645 pol . addPoint ( xt + xoff + s2 , yt + yoff + s2 ) ;
646 pol . addPoint ( xt + xoff - s2 , yt + yoff + s2 ) ;
647 toolTip . addElement ( pol ) ;
648 break ;
649 } // end switch s t a t e m e n t
650
651 // check for P o i n t T e x t
652 if ( dp . getPointTexts () != null ) {
653 String t = ( String ) dp . getPointText ( i ) ;
654 // int tc = (( Long ) dp . getTcol ( i ) ) . i n t V a l u e () ;
655 Color tColor = dp . g e t P o i n t T e x t C o l o r ( i ) ;
656 // Color tColor = new Color ( ( int ) (0 x f f f f f f 0 0 & tc ) >> 8) ;
657 int tLook = dp . g e t P o i n t T e x t L o o k ( i ) ;
658 int tSize = dp . g e t P o i n t T e x t S i z e ( i ) ;
659 if ( tSize < 8 || tSize > 14) {
660 tSize = fontHeight ( Math . min ( height , width ) / 20 , 8 , 14) ;
661 // int tLook = (( int ) (0 x 0 0 0 0 0 0 f 0 & tc ) >> 4) - 1;
662 // int tSize = ( int ) (0 x 0 0 0 0 0 0 0 f & tc ) ;
663
664 }
665 Font f = new Font ( " TimesRoman " , 0 , tSize ) ;
666 g2D . setColor ( tColor ) ;
667 g2D . setFont ( f ) ;
668 FontMetrics fm = g2D . get Fon tM etr ic s ( f ) ;
188
B.14 XPlot.java
189
XQC Source Code
764 ytOld = yt ;
765 }
766
767 } // end p a i n t i n g lines
768 } // end handle lines
769
770 } // end handle graphic output
771 } // end loop for number of data parts
772 this . requestFocus () ;
773
774 // a little roll back - i m p o r t a n t for the print routine
775 if ( type == 1) {
776 g2D . translate (0 - xoff , 0 - yoff ) ;
777 }
778 g2D . setStroke ( new BasicStroke (1 , BasicStroke . CAP_BUTT , BasicStroke . JOIN_MITER , 10) ) ;
779 }
780
781 private double equalValueMin ( double min ) {
782 if ( min == 0.0) {
783 min = -0.1;
784 }
785 else {
786 if ( Math . abs ( min * 0.9 - min ) > 1) {
787 min = min - 1;
788 }
789 else {
790 min = min * 0.9;
791 }
792 }
793 return min ;
794 }
795
796 private double equalValueMax ( double max ) {
797 if ( max == 0.0) {
798 max = 0.1;
799 }
800 else {
801 if ( Math . abs ( max * 1.1 - max ) > 1) {
802 max = max + 1;
803 }
804 else {
805 max = max * 1.1;
806 }
807 }
808 return max ;
809 }
810
811 // set rMat to show XY
812 protected void rMatXY () {
813 rMat = new double [][] {{1 , 0 , 0} , {0 , 1 , 0} , {0 , 0 , 1}};
814 repaint () ;
815 }
816
817 // set rMat to show XZ
818 protected void rMatXZ () {
819 rMat = new double [][] {{1 , 0 , 0} , {0 , 0 , 1} , {0 , 1 , 0}};
820 repaint () ;
821 }
822
823 // set rMat to show YZ
824 protected void rMatYZ () {
825 rMat = new double [][] {{0 , 0 , 1} , {1 , 0 , 0} , {0 , 1 , 0}};
826 repaint () ;
827 }
828
829 // c a l c u l a t e the rotated d a t a p o i n t
830 private void rotate ( int k , int size ) {
831 xRot = new double [ dp . g e t N u mb e r O f Ro w s () ];
832 yRot = new double [ dp . g e t N u mb e r O f Ro w s () ];
833 zRot = new double [ dp . g e t N u mb e r O f Ro w s () ];
834 for ( int i = 0; i < dp . g et N u m b er O f R o ws () ; i ++) {
835 xRot [ i ] = ( x [ k ][ i ] * rMat [0][0]) + ( y [ k ][ i ] * rMat [1][0]) + ( z [ k ][ i ] * rMat [2][0]) ;
836 yRot [ i ] = ( x [ k ][ i ] * rMat [0][1]) + ( y [ k ][ i ] * rMat [1][1]) + ( z [ k ][ i ] * rMat [2][1]) ;
837 zRot [ i ] = ( x [ k ][ i ] * rMat [0][2]) + ( y [ k ][ i ] * rMat [1][2]) + ( z [ k ][ i ] * rMat [2][2]) ;
838 xRot [ i ] = xRot [ i ] * size / 1.5;
839 yRot [ i ] = yRot [ i ] * size / 1.5;
840 }
841 }
842
843 private int setTitle ( int width , int xoff , int height , Graphics2D gr , String title ) {
844 // get frame p r o p e r t i e s
845 int frheight = height ;
846 int frwidth = width ;
847 double a = Math . min ( frheight , frwidth ) / 20;
848 double b = frheight / 40;
849 // i n i t i a t e fonts
850 int fontheight = fontHeight (a , 8 , 20) ;
851 int addon_y_pos = fontHeight (b , 8 , 20) ;
852 Font font = new Font ( " TimesRoman " , Font . BOLD , fontheight ) ;
853 gr . setFont ( font ) ;
854 // get title p r o p e r t i e s
855 FontMetrics metric = gr . ge tF ont Me tri cs ( font ) ;
856 int xwidth = metric . stringWidth ( title ) ;
857 // i n i t i a t e some v a r i a b l e s
858 int halfwidth , halfxwidth , xo , yo ;
859 int chheight = 2 * metric . getHeight () ;
190
B.14 XPlot.java
191
XQC Source Code
956 }
957 rMat = temp ;
958 repaint () ;
959 }
960
961 // rotate right
962 if ( keyCode == 39) {
963 // System . out . println (" right ") ;
964 double [][] temp = new double [3][3];
965 for ( int i = 0; i < 3; i ++) {
966 for ( int j = 0; j < 3; j ++) {
967 temp [ i ][ j ] = ( rMat [ i ][0] * rMatXZ [0][ j ]) + ( rMat [ i ][1] * rMatXZ [1][ j ]) +
968 ( rMat [ i ][2] * rMatXZ [2][ j ]) ;
969 }
970 }
971 rMat = temp ;
972 repaint () ;
973 }
974
975 // rotate down
976 if ( keyCode == 40) {
977 // System . out . println (" down ") ;
978 double [][] temp = new double [3][3];
979 for ( int i = 0; i < 3; i ++) {
980 for ( int j = 0; j < 3; j ++) {
981 temp [ i ][ j ] = ( rMat [ i ][0] * rMatZY [0][ j ]) + ( rMat [ i ][1] * rMatZY [1][ j ]) +
982 ( rMat [ i ][2] * rMatZY [2][ j ]) ;
983 }
984 }
985 rMat = temp ;
986 repaint () ;
987 }
988 }
989 }
990
991 // print routine
992 public int print ( Graphics g , PageFormat pf , int pi ) throws P r i n t e r E x c e p t i o n {
993 if ( pi >= 1) {
994 return Printable . NO_SUCH_PAGE ;
995 }
996
997 int w = this . getWidth () ;
998 int h = this . getHeight () ;
999
1000 if ( w > pf . g e t I m a g e a b l e W i d t h () ) {
1001 double temp = pf . g e t I m a g e a b l e W i d t h () / w ;
1002 w = ( int ) ( w * temp ) ;
1003 h = ( int ) ( h * temp ) ;
1004 }
1005 if ( h > pf . g e t I m a g e a b l e H e i g h t () ) {
1006 double temp = pf . g e t I m a g e a b l e H e i g h t () / h ;
1007 w = ( int ) ( w * temp ) ;
1008 h = ( int ) ( h * temp ) ;
1009 }
1010
1011 Graphics2D gr2d = ( Graphics2D ) g ;
1012 gr2d . translate ( pf . getImageableX () , pf . getImageableY () ) ;
1013 drawPlot ( gr2d , w , h ) ;
1014 return Printable . PAGE_EXISTS ;
1015 }
1016
1017 protected void c h e ck F o r To o l T i p ( int xtt , int ytt ) {
1018 boolean chk = false ;
1019 this . ttText = null ;
1020 int j = 0;
1021 // data parts
1022 for ( int k = 0; k < ndp ; k ++) {
1023 dp = ( XQSDataObject ) obj . getDataObject ( k ) ;
1024 // e l e m e n t s of data part
1025 for ( int i = 0; i < dp . g et N u m b er O f R ow s () ; i ++) {
1026 if ( k > 0) {
1027 j = i + ( ( XQSDataObject ) obj . getDataObject ( k - 1) ) . g e tN u m b e rO f R o w s () ;
1028 }
1029 else {
1030 j = i;
1031 }
1032 if ( j >= toolTip . size () ) {
1033 break ;
1034 }
1035 if ( ( ( Polygon ) toolTip . elementAt ( j ) ) . contains ( xtt , ytt ) ) {
1036 if ( dim == 3) {
1037 xOrg [ k ][ i ] = ( Math . round ( xOrg [ k ][ i ] * 100) ) ;
1038 xOrg [ k ][ i ] = xOrg [ k ][ i ] / 100;
1039 yOrg [ k ][ i ] = ( Math . round ( yOrg [ k ][ i ] * 100) ) ;
1040 yOrg [ k ][ i ] = yOrg [ k ][ i ] / 100;
1041 zOrg [ k ][ i ] = ( Math . round ( zOrg [ k ][ i ] * 100) ) ;
1042 zOrg [ k ][ i ] = zOrg [ k ][ i ] / 100;
1043 if ( ttText == null ) {
1044 ttText = " < html > < font size = -1 > " + disp . frame . client . XOpt . XQCJ002 + " " + ( k + 1) +
1045 " / " + ( i + 1) + " [ " + xOrg [ k ][ i ] + " , " + yOrg [ k ][ i ] + " , " + zOrg [ k ][ i ] +
1046 " ] </ font > </ html > " ;
1047 }
1048 else {
1049 ttText = ttText . substring (0 , ttText . length () - 14) + " <p > " +
1050 disp . frame . client . XOpt . XQCJ002 + " " + ( k + 1) + " / " + ( i + 1) + " [ " + xOrg [ k ][
i] +
192
B.14 XPlot.java
1051 " , " + yOrg [ k ][ i ] + " , " + zOrg [ k ][ i ] + " ] </ font > </ html > " ;
1052 }
1053 }
1054 else {
1055 xOrg [ k ][ i ] = ( Math . round ( xOrg [ k ][ i ] * 100) ) ;
1056 xOrg [ k ][ i ] = xOrg [ k ][ i ] / 100;
1057 yOrg [ k ][ i ] = ( Math . round ( yOrg [ k ][ i ] * 100) ) ;
1058 yOrg [ k ][ i ] = yOrg [ k ][ i ] / 100;
1059 if ( ttText == null ) {
1060 ttText = " < html > < font size = -1 > " + disp . frame . client . XOpt . XQCJ002 + " " + ( k + 1) +
1061 " / " + ( i + 1) + " [ " + xOrg [ k ][ i ] + " , " + yOrg [ k ][ i ] + " ] </ font > </ html > " ;
1062 }
1063 else {
1064 ttText = ttText . substring (0 , ttText . length () - 14) + " <p > " +
1065 disp . frame . client . XOpt . XQCJ002 + " " + ( k + 1) + " / " + ( i + 1) + " [ " + xOrg [ k ][
i] +
1066 " , " + yOrg [ k ][ i ] + " ] </ font > </ html > " ;
1067 }
1068 }
1069 this . set Too lT ipT ex t ( ttText ) ;
1070 chk = true ;
1071 }
1072 }
1073 }
1074 if (! chk ) {
1075 this . set Too lT ipT ex t ( null ) ;
1076 }
1077 }
1078
1079 protected int getDim () {
1080 return dim ;
1081 }
1082
1083 }
193
XQC Source Code
B.15 XPlotAction.java
1 package xqc ;
2
3 import java . awt . event .*;
4 import javax . swing .*;
5 import java . awt . print . PrinterJob ;
6
7 /* *
8 * <p > XClient - X P l o t A c t i o n - handles the action of a single plot </ p >
9 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
10 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
11 * @ v e r s i o n March 2004
12 */
13 class XPlotAction
14 implements ActionListener , ItemListener , KeyListener , MouseListener , MouseMotionListener ,
15 FocusListener {
16 private XPlot plot = null ;
17 private JPopupMenu popup = null ;
18 private JMenuItem print = null ;
19 private J C h e c k B o x M e n u I t e m cbToolTip = null ;
20 private boolean setToolTip = false ;
21 private int prevx = 0;
22 private int prevy = 0;
23 private double xTheta ;
24 private double yTheta ;
25 private boolean showCopyRight = false ;
26
27 protected XPlotAction ( XPlot plot ) {
28 this . plot = plot ;
29
30 popup = new JPopupMenu () ;
31
32 print = new JMenuItem ( plot . disp . frame . client . XOpt . XQCK001 ) ;
33 print . s e t A c t i o n C o m m a n d ( " Print single plot ... " ) ;
34 print . a d d A c t i o n L i s t e n e r ( this ) ;
35 popup . add ( print ) ;
36
37 popup . addSeparator () ;
38
39 cbToolTip = new J C h e c k B o x M e n u I t e m ( plot . disp . frame . client . XOpt . XQCK002 ) ;
40 cbToolTip . s e t A c t i o n C o m m a n d ( " Show coordinates " ) ;
41 cbToolTip . ad d I t e mL i s t e ne r ( this ) ;
42 popup . add ( cbToolTip ) ;
43
44 if ( plot . getDim () == 3) {
45 JMenuItem showXY = new JMenuItem ( plot . disp . frame . client . XOpt . XQCK003 + " X ~ Y " ) ;
46 showXY . s e t A c t i o n C o m m a n d ( " Show X ~ Y " ) ;
47 showXY . a d d A c t i o n L i s t e n e r ( this ) ;
48 popup . add ( showXY ) ;
49
50 JMenuItem showXZ = new JMenuItem ( plot . disp . frame . client . XOpt . XQCK003 + " X ~ Z " ) ;
51 showXZ . s e t A c t i o n C o m m a n d ( " Show X ~ Z " ) ;
52 showXZ . a d d A c t i o n L i s t e n e r ( this ) ;
53 popup . add ( showXZ ) ;
54
55 JMenuItem showYZ = new JMenuItem ( plot . disp . frame . client . XOpt . XQCK003 + " Y ~ Z " ) ;
56 showYZ . s e t A c t i o n C o m m a n d ( " Show Y ~ Z " ) ;
57 showYZ . a d d A c t i o n L i s t e n e r ( this ) ;
58 popup . add ( showYZ ) ;
59 }
60
61 /*
62 // C o p y R i g h t for stand - alone XQCPlot
63 popup . a d d S e p a r a t o r () ;
64 J M e n u I t e m c o p y R i g h t = new J M e n u I t e m (" C o p y r i g h t - MD * Tech ") ;
65 c o p y R i g h t . s e t B a c k g r o u n d ( new java . awt . Color (255 , 255 , 255) ) ;
66 c o p y R i g h t . a d d A c t i o n L i s t e n e r ( this ) ;
67 c o p y R i g h t . s e t A c t i o n C o m m a n d (" c o p y R i g h t ") ;
68 popup . add ( c o p y R i g h t ) ;
69 */
70 }
71
72 public void a c t io n P e r fo r m e d ( ActionEvent e ) {
73 String arg = e . g e t A c t i o n C o m m a n d () ;
74
75 if ( arg . equals ( " Print single plot ... " ) ) {
76 PrinterJob printJob = PrinterJob . getPrinterJob () ;
77 printJob . setPrintable ( plot ) ;
78 if ( printJob . printDialog () ) {
79 try {
80 printJob . print () ;
81 // plot . pf = null ;
82 }
83 catch ( Exception ex ) {
84 ex . p r i n tS t a c kT r a c e () ;
85 }
86 }
87 }
88
89 if ( arg . equals ( " Show X ~ Y " ) ) {
90 plot . rMatXY () ;
91 }
92
194
B.15 XPlotAction.java
195
XQC Source Code
189
190 public void focusGained ( FocusEvent e ) {
191 plot . s et Too lT ipT ext ( " " ) ;
192 }
193
194 }
196
B.16 XSetGOpt.java
B.16 XSetGOpt.java
1 package xqc ;
2
3 import javax . swing .*;
4 import com . mdcrypt . mdcrypt .*;
5 import java . util .*;
6
7 /* *
8 * <p > X S e t G O p t - handles Xplore ’s SetGOpt </ p >
9 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
10 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
11 * @ v e r s i o n March 2004
12 */
13 class XSetGOpt {
14 private XDisplayFrame frame = null ;
15 private XDisplay disp = null ;
16 private XPlot plot = null ;
17
18 protected XSetGOpt ( XDisplay disp ) {
19 super () ;
20 this . disp = disp ;
21 }
22
23 protected XSetGOpt ( XDisplay disp , XDisplayFrame frame ) {
24 super () ;
25 this . disp = disp ;
26 this . frame = frame ;
27 }
28
29 protected void setOptions ( X Q S S e t G O p t O b j e c t obj ) {
30
31 if ( frame . isClosed () ) {
32 System . out . println ( " Display not found ! " ) ;
33 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( frame . client , XDialog . ERROR ,
34 frame . client . XOpt . XQCL001 ) ;
35 return ;
36 }
37
38 if ( disp == null ) {
39 System . out . println ( " Display not found ! " ) ;
40 return ;
41 }
42
43 plot = disp . getPlot ( obj . getRows () , obj . getCols () ) ;
44
45 if ( plot == null ) {
46 new XDialog () . s h o w S t r i n g C o n f i r m a t i o n D i a l o g ( frame . client , XDialog . ERROR ,
47 frame . client . XOpt . XQCL002 ) ;
48 System . out . println ( " \" show \" needs to be before \" setgopt \" " ) ;
49 return ;
50 }
51
52 // handle title
53 if ( obj . getTitle () != null ) {
54 plot . title = obj . getTitle () ;
55 plot . repaint () ;
56 }
57
58 // handle x - label
59 if ( obj . getXLabel () != null ) {
60 plot . xLabel = obj . getXLabel () ;
61 plot . repaint () ;
62 }
63
64 // handle y - label
65 if ( obj . getYLabel () != null ) {
66 plot . yLabel = obj . getYLabel () ;
67 plot . repaint () ;
68 }
69
70 // handle setSize
71 if ( obj . g e t D i sp l a y s iz e x () != 0 && obj . ge t D i s pl a y s iz e y () != 0) {
72 if ( frame != null ) {
73 frame . h a n d l e S e t G O p t _ s e t S i z e ( obj . g e t Di s p l ay s i z e x () , obj . g et D i s p la y s i z ey () ) ;
74 }
75 }
76
77 // handle a x e s V i s i b i l i t y
78 plot . s e t A x e s V i s i b i l i t y ( obj . getIsXaxis () , obj . getIsYaxis () ) ;
79
80 // handle border ( for p r i n t i n g frame )
81 if ( obj . getBorder () ) {
82 plot . border = 1;
83 }
84 else {
85 plot . border = 0;
86 }
87 }
88
89 }
197
XQC Source Code
B.17 XReadValue.java
1 package xqc ;
2
3 import javax . swing .*;
4 import java . awt .*;
5 import java . awt . event .*;
6 import com . mdcrypt . mdcrypt .*;
7
8 /* *
9 * <p > X R e a d V a l u e - handles Xplore ’s ReadValue </ p >
10 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
11 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
12 * @ v e r s i o n March 2004
13 */
14 class XReadValue
15 extends JDialog
16 implements ActionListener , KeyListener {
17
18 private JTextField [] v = null ;
19 private X Q S R e a d V a l u e O b j e c t obj = null ;
20 private int type = 0;
21
22 protected XReadValue ( XClient client , X Q S R e a d V a l u e O b j e c t obj ) {
23 super ( client , client . XOpt . XQCZ901 , true ) ;
24 this . obj = obj ;
25
26 type = obj . getDataType () ;
27 int n = ( obj . getNames () ) . length ;
28 int length = 0;
29 v = new JTextField [ n ];
30
31 JPanel p1 = new JPanel () ;
32 p1 . setLayout ( new GridLayout (n , 2) ) ;
33 p1 . setBorder ( BorderFactory . c r e a t e E m p t y B o r d e r (5 , 5 , 5 , 5) ) ;
34 for ( int i = 0; i < n ; i ++) {
35 // c a l c u l a t e the max length of a name
36 if ( length < ( obj . getNames ( i ) ) . length () ) {
37 length = ( obj . getNames ( i ) ) . length () ;
38 }
39 p1 . add ( new JLabel ( obj . getNames ( i ) ) ) ;
40 if ( type == 1) {
41 v [ i ] = new JTextField ( " " + obj . getValue ( i ) ) ;
42 v [ i ]. setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . TEXT_CURSOR ) ) ;
43 }
44 else {
45 v [ i ] = new JTextField ( " " + obj . getTextValue ( i ) ) ;
46 v [ i ]. setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . TEXT_CURSOR ) ) ;
47 }
48 p1 . add ( v [ i ]) ;
49 v [ i ]. a dd Key Lis te ner ( this ) ;
50 }
51 JScrollPane scrollPane = new JScrollPane ( p1 ) ;
52 ge tC ont ent Pa ne () . add ( scrollPane , " Center " ) ;
53
54 JPanel p2 = new JPanel () ;
55 JButton ok = new JButton ( " Ok " ) ;
56 ok . setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . HAND_CURSOR ) ) ;
57 p2 . add ( ok ) ;
58 ge tC ont ent Pa ne () . add ( p2 , " South " ) ;
59 ok . a d d A c t i o n L i s t e n e r ( this ) ;
60
61 int h = n * 20 + 100;
62 if ( client . ISAPPLET == true ) {
63 h = h + 50;
64 }
65 setSize ( Math . max (200 , length * 20) , Math . min (h , 300) ) ;
66 center () ;
67 show () ;
68
69 }
70
71 private void center () {
72 /* C a l c u l a t e the screen size */
73 Dimension screenSize = Toolkit . g e t D e f a u l t T o o l k i t () . getScreenSize () ;
74
75 /* Center frame on the screen */ Dimension frameSize = this . getSize () ;
76 if ( frameSize . height > screenSize . height ) {
77 frameSize . height = screenSize . height ;
78 }
79 if ( frameSize . width > screenSize . width ) {
80 frameSize . width = screenSize . width ;
81 }
82 this . setLocation ( ( screenSize . width - frameSize . width ) / 2 ,
83 ( screenSize . height - frameSize . height ) / 2) ;
84 }
85
86 public void a c t io n P e r fo r m e d ( ActionEvent e ) {
87 try {
88 if ( e . g e t A c t i o n C o m m a n d () == " Ok " ) {
89 for ( int i = 0; i < ( obj . getNames () ) . length ; i ++) {
90 if ( type == 1) {
91 obj . setValue (i , Double . valueOf ( ( String ) v [ i ]. getText () ) . doubleValue () ) ;
92 }
198
B.17 XReadValue.java
93 else {
94 obj . setTextValue (i , ( String ) v [ i ]. getText () ) ;
95 }
96 }
97 dispose () ;
98 }
99 }
100 catch ( Exception e1 ) {
101 System . out . println ( e1 ) ;
102 }
103 }
104
105 public void keyPressed ( KeyEvent e ) {
106 try {
107 if ( e . getKeyCode () == 10) {
108 for ( int i = 0; i < ( obj . getNames () ) . length ; i ++) {
109 if ( type == 1) {
110 obj . setValue (i , Double . valueOf ( ( String ) v [ i ]. getText () ) . doubleValue () ) ;
111 }
112 else {
113 obj . setTextValue (i , ( String ) v [ i ]. getText () ) ;
114 }
115 }
116 dispose () ;
117 }
118 }
119 catch ( Exception e1 ) {
120 System . out . println ( e1 ) ;
121 }
122 }
123
124 public void keyReleased ( KeyEvent e ) {
125 }
126
127 public void keyTyped ( KeyEvent e ) {
128 }
129
130 }
199
XQC Source Code
B.18 XSelectItem.java
1 package xqc ;
2
3 import javax . swing .*;
4 import javax . swing . event .*;
5 import java . awt .*;
6 import java . awt . event .*;
7 import com . mdcrypt . mdcrypt .*;
8
9 /* *
10 * <p > X S e l e c t I t e m - handles Xplore ’s SelectItem </ p >
11 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
12 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
13 * @ v e r s i o n March 2004
14 */
15 class XSelectItem
16 extends JDialog
17 implements ActionListener , ListSelectionListener , KeyListener , ItemListener {
18
19 private JList list = null ;
20 private JCheckBox checkBox = null ;
21 private D e f a u l t L i s t M o d e l listModel = new D e f a u l t L i s t M o d e l () ;
22 private int [] indices ;
23 private int [] selection ;
24 private X Q S S e l e c t I t e m O b j e c t obj = null ;
25 private int type = 0;
26 private int noOfItems = 0;
27
28 protected XSelectItem ( XClient client , X Q S S e l e c t I t e m O b j e c t obj ) {
29 super ( client , client . XOpt . XQCZ902 , true ) ;
30 this . obj = obj ;
31 this . setEnabled ( true ) ;
32
33 this . setTitle ( obj . getTitle () ) ;
34 noOfItems = ( obj . getNames () ) . length ;
35 int length = 0;
36 // c a l c u l a t e the max length of a name
37 for ( int i = 0; i < noOfItems ; i ++) {
38 if ( length < ( obj . getNames ( i ) ) . length () ) {
39 length = ( obj . getNames ( i ) ) . length () ;
40 }
41 listModel . addElement ( obj . getNames ( i ) ) ;
42 }
43
44 list = new JList ( listModel ) ;
45 list . s e t S e l e c t i o n M o d e ( L i s t S e l e c t i o n M o d e l . M U L T I P L E _ I N T E R V A L _ S E L E C T I O N ) ;
46 list . setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . HAND_CURSOR ) ) ;
47 list . setBackground ( new Color (255 , 255 , 255) ) ;
48 list . a d d L i s t S e l e c t i o n L i s t e n e r ( this ) ;
49 list . add Key Li ste ne r ( this ) ;
50
51 JPanel p1 = new JPanel () ;
52 p1 . setLayout ( new GridLayout ( noOfItems , 1) ) ;
53 p1 . setBorder ( BorderFactory . c r e a t e E m p t y B o r d e r (5 , 5 , 5 , 5) ) ;
54
55 for ( int i = 0; i < noOfItems ; i ++) {
56 checkBox = new JCheckBox ( obj . getNames ( i ) ) ;
57 checkBox . setName ( " " + i ) ;
58 checkBox . a d d I t em L i s t en e r ( this ) ;
59 p1 . add ( checkBox ) ;
60 }
61 selection = new int [ noOfItems ];
62
63 JScrollPane scrollPane = new JScrollPane ( p1 ) ;
64 ge tC ont ent Pa ne () . add ( scrollPane , " Center " ) ;
65
66 JPanel p2 = new JPanel () ;
67 JButton ok = new JButton ( " Ok " ) ;
68 ok . setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . HAND_CURSOR ) ) ;
69 p2 . add ( ok ) ;
70 JButton cl = new JButton ( " Cancel " ) ;
71 cl . setCursor ( Cursor . g e t P r e d e f i n e d C u r s o r ( Cursor . HAND_CURSOR ) ) ;
72 p2 . add ( cl ) ;
73 ge tC ont ent Pa ne () . add ( p2 , " South " ) ;
74 ok . a d d A c t i o n L i s t e n e r ( this ) ;
75 cl . a d d A c t i o n L i s t e n e r ( this ) ;
76
77 int h = noOfItems * 15 + 120;
78 if ( client . ISAPPLET == true ) {
79 h = h + 50;
80 }
81 setSize ( Math . max ( length * 10 , 150) , Math . min (h , 300) ) ;
82 center () ;
83 show () ;
84
85 }
86
87 private void center () {
88 /* C a l c u l a t e the screen size */
89 Dimension screenSize = Toolkit . g e t D e f a u l t T o o l k i t () . getScreenSize () ;
90
91 /* Center frame on the screen */ Dimension frameSize = this . getSize () ;
92 if ( frameSize . height > screenSize . height ) {
200
B.18 XSelectItem.java
201
XQC Source Code
202
Appendix C
The following class is not part of the XQC. It just shows how the plot classes
can easily be used within a third party program.
C.1 ThirdPartyClient.java
1 import xqcplot .*;
2 import com . mdcrypt . mdcrypt .*;
3 import javax . swing .*;
4 import java . awt . event .*;
5
6 /* *
7 * <p > XQCPlot - test application </ p >
8 * <p > C o p y r i g h t : C o p y r i g h t ( c ) 2004 MD * Tech </ p >
9 * @author Heiko Lehmann - m a i l @ h l e h m a n n . de
10 * @ v e r s i o n March 2004
11 */
12 public class T h i r d P a r t y C l i e n t
13 extends JFrame
14 implements XQSListener {
15 XQServer s ; // com . mdcrypt . mdcrypt . X Q S e r v e r
16 XDisplay disp ; // xqcplot . X D i s p l a y
17
18 public T h i r d P a r t y C l i e n t () {
19 super ( " TestClient " ) ;
20
21 s = new XQServer () ; // i n i t i a l i z e the X Q S e r v e r
22 s . setServerIP ( " localhost " ) ; // set the IP address of the XQS
23 s . setServerPort (4451) ; // set the port of the XQS
24 s . addListener ( this ) ; // add a X Q S L i s t e n e r to the server
25 // to handle server replies
26 try {
27 s . connect () ; // connect to the server
28 }
29 catch ( Exception se ) {
30 System . out . println ( " Connect - Exeception " ) ;
31 }
32
33 this . a d d W i n d o w L i s t e n e r ( new java . awt . event . WindowAdapter () {
34 public void windowClosing ( WindowEvent e ) {
35 try {
36 s . terminate () ;
37 }
38 catch ( Exception se ) {
203
Example of a Third Party Client
204
Erklärung
Hiermit erkläre ich, die vorliegende Arbeit selbständig und ohne fremde Hilfe
verfasst und nur angegebene Literatur und Hilfsmittel verwendet zu haben.
Personen, von denen ich Unterstützung erhalten habe, sind in der Danksa-
gung genannt. Die vorliegende Dissertation war weder vollständig noch in
Teilen Gegenstand einer früheren Begutachtung.
Ich bezeuge durch meine Unterschrift, dass meine Angaben über die bei der
Abfassung meiner Dissertation benutzten Hilfsmittel, über die mir zuteil ge-
wordene Hilfe sowie über frühere Begutachtungen meiner Dissertation in je-
der Hinsicht der Wahrheit entsprechen.
Heiko Lehmann
02. April 2004
205