Upload sources

This commit is contained in:
khanhduytran0 committed 2020-03-19 16:42:25 +07:00
1 parent 86083535a8
commit e1ce65eb29
2887 files changed
+85891

No files matched your search

@@ -0,0 +1,36 @@
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.graphics;
import java.lang.reflect.*;
/**
* PixelXorXfermode implements a simple pixel xor (op ^ src ^ dst).
* This transformation does not follow premultiplied conventions, therefore
* this mode *always* returns an opaque color (alpha == 255). Thus it is
* not really usefull for operating on blended colors.
*/
@Deprecated
public class PixelXorXfermode extends Xfermode {
public PixelXorXfermode(int opColor) {
try {
Field field_nativeInstance = getClass().getDeclaredField("native_instance");
field_nativeInstance.setAccessible(true);
field_nativeInstance.set(null, nativeCreate(opColor));
} catch (Exception e) {
e.printStackTrace();
}
}
private static native int nativeCreate(int opColor);
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

@@ -0,0 +1,120 @@
package com.kdt.filerapi;
/*
* Copyright (C) 2012 Paul Burke
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.content.*;
import android.view.*;
import android.widget.*;
import java.io.*;
import java.util.*;
import net.kdt.pojavlaunch.*;
/**
* List adapter for Files.
*
* @version 2013-12-11
* @author paulburke (ipaulpro)
*
* @addDate 2018-08-08
* @addToMyProject khanhduy032 (kdt032)
*/
public class FileListAdapter extends BaseAdapter {
private final static int ICON_FOLDER = R.drawable.ic_folder;
private final static int ICON_FILE = R.drawable.ic_file;
private final LayoutInflater mInflater;
private List<File> mData = new ArrayList<File>();
public FileListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public void add(File file) {
mData.add(file);
notifyDataSetChanged();
}
public void remove(File file) {
mData.remove(file);
notifyDataSetChanged();
}
public void insert(File file, int index) {
mData.add(index, file);
notifyDataSetChanged();
}
public void clear() {
mData.clear();
notifyDataSetChanged();
}
@Override
public File getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getCount() {
return mData.size();
}
public List<File> getListItems() {
return mData;
}
/**
* Set the list items without notifying on the clear. This prevents loss of
* scroll position.
*
* @param data
*/
public void setListItems(List<File> data) {
mData = data;
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null)
row = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
TextView view = (TextView) row;
// Get the file at the current position
final File file = getItem(position);
// Set the TextView as the file name
view.setText(file.getName());
// If the item is not a directory, use the file icon
int icon = file.isDirectory() ? ICON_FOLDER : ICON_FILE;
view.setCompoundDrawablesWithIntrinsicBounds(icon, 0, 0, 0);
return row;
}
}
@@ -0,0 +1,170 @@
package com.kdt.filerapi;
import android.content.*;
import android.graphics.*;
import android.os.*;
import android.support.annotation.*;
import android.util.*;
import android.view.*;
import android.widget.*;
import android.widget.AdapterView.*;
import java.io.*;
import java.util.*;
public class FileListView extends LinearLayout
{
//For list view:
private String fullPath;
private TextView mainTv;
private ListView mainLv;
private Context context;
//For message empty:
private WindowManager emptyWm;
private TextView emptyTv;
//For File selected listener:
private FileSelectedListener listener;
public FileListView(Context context)
{
super(context);
init(context);
}
public FileListView(Context context, AttributeSet attrs)
{
super(context, attrs);
init(context);
}
public FileListView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init(context);
}
public void init(final Context context)
{
//Empty message setup:
WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
mParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mParams.gravity = Gravity.CENTER;
mParams.format = PixelFormat.TRANSLUCENT;
mParams.type = WindowManager.LayoutParams.TYPE_APPLICATION;
mParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
emptyWm = (WindowManager) context.getSystemService(context.WINDOW_SERVICE);
emptyTv = new TextView(context);
emptyTv.setText("This folder is empty");
emptyWm.addView(emptyTv, mParams);
//Main setup:
this.context = context;
LayoutParams layParam = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
setOrientation(VERTICAL);
mainTv = new TextView(context);
mainTv.setText("Path: null");
mainLv = new ListView(context);
listFileAt(Environment.getExternalStorageDirectory().getPath());
mainLv.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> p1, View p2, int p3, long p4)
{
// TODO: Implement this method
File mainFile = new File(p1.getItemAtPosition(p3).toString());
String name = mainFile.getName();
//Toast.makeText(MainActivity.this, name, Toast.LENGTH_LONG).show();
if(name.equals(".. ")){
parentDir();
}
else{
listFileAt(mainFile.getAbsolutePath());
}
}
});
addView(mainTv, layParam);
addView(mainLv, layParam);
}
public void setFileSelectedListener(FileSelectedListener listener)
{
this.listener = listener;
}
public void listFileAt(final String path)
{
try{
final File mainPath = new File(path);
if(mainPath.exists()){
if(mainPath.isDirectory()){
fullPath = path;
File[] listFile = mainPath.listFiles();
FileListAdapter fileAdapter = new FileListAdapter(context);
fileAdapter.add(new File(path, ".. "));
if(listFile.length != 0){
Arrays.sort(listFile, new SortFileName());
for(File file : listFile){
fileAdapter.add(file);
}
emptyTv.setVisibility(View.GONE);
}
else{
emptyTv.setVisibility(View.VISIBLE);
}
mainLv.setAdapter(fileAdapter);
mainTv.setText("Path: " + path);
}
else{
String name = mainPath.getName();
String extension = getExtension(path);
listener.onFileSelected(mainPath, path, name, extension);
}
}
else{
Toast.makeText(context, "This folder (or file) doesn't exist", Toast.LENGTH_SHORT).show();
refreshPath();
}
}
catch(Exception e){
/*
new AlertDialog.Builder(context)
.setTitle("Error")
.setMessage(Log.getStackTraceString(e))
.setPositiveButton("OK", null)
.show();
*/
}
}
public static String getExtension(String path)
{
return getExtension(new File(path));
}
public static String getExtension(File file)
{
return file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf("."));
}
public String getFullPath()
{
return fullPath;
}
public void refreshPath()
{
listFileAt(getFullPath());
}
public void parentDir()
{
File pathFile = new File(fullPath);
if(!pathFile.getAbsolutePath().equals(Environment.getExternalStorageDirectory().getAbsolutePath())){
listFileAt(pathFile.getParent());
}
}
}
@@ -0,0 +1,8 @@
package com.kdt.filerapi;
import java.io.File;
public interface FileSelectedListener
{
public void onFileSelected(File file, String path, String nane, String extension);
}
@@ -0,0 +1,13 @@
package com.kdt.filerapi;
import java.io.*;
import java.util.*;
public class SortFileName implements Comparator<File>
{
@Override
public int compare(File f1, File f2) {
return f1.getName().compareToIgnoreCase(f2.getName());
}
}
@@ -0,0 +1,112 @@
package com.kdt.filermod;
/*
* Copyright (C) 2012 Paul Burke
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import android.content.*;
import android.view.*;
import android.widget.*;
import java.io.*;
import java.util.*;
/**
* List adapter for Files.
*
* @version 2013-12-11
* @author paulburke (ipaulpro)
*
* @addDate 2018-08-08
* @addToMyProject khanhduy032 (kdt032)
*/
public class MFileListAdapter extends BaseAdapter {
private final LayoutInflater mInflater;
private List<File> mData = new ArrayList<File>();
public MFileListAdapter(Context context) {
mInflater = LayoutInflater.from(context);
}
public void add(File file) {
mData.add(file);
notifyDataSetChanged();
}
public void remove(File file) {
mData.remove(file);
notifyDataSetChanged();
}
public void insert(File file, int index) {
mData.add(index, file);
notifyDataSetChanged();
}
public void clear() {
mData.clear();
notifyDataSetChanged();
}
@Override
public File getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getCount() {
return mData.size();
}
public List<File> getListItems() {
return mData;
}
/**
* Set the list items without notifying on the clear. This prevents loss of
* scroll position.
*
* @param data
*/
public void setListItems(List<File> data) {
mData = data;
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null)
row = mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
TextView view = (TextView) row;
// Get the file at the current position
final File file = getItem(position);
// Set the TextView as the file name
view.setText(file.getName());
return row;
}
}
@@ -0,0 +1,167 @@
package com.kdt.filermod;
import android.app.*;
import android.content.*;
import android.graphics.*;
import android.os.*;
import android.util.*;
import android.view.*;
import android.widget.*;
import android.widget.AdapterView.*;
import java.io.*;
import java.util.*;
import net.kdt.pojavlaunch.*;
public class MFileListView extends LinearLayout
{
//For list view:
private String fullPath;
private ListView mainLv;
private Context context;
private boolean lockedHome = false;
//For File selected listener:
private MFileSelectedListener listener;
private AlertDialog build;
private String homePath;
public MFileListView(Context context, AlertDialog build)
{
super(context);
init(context);
this.build = build;
}
public MFileListView(Context context, AttributeSet attrs)
{
super(context, attrs);
init(context);
}
public MFileListView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init(context);
}
public void init(final Context context)
{
//Main setup:
this.context = context;
LayoutParams layParam = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
setOrientation(VERTICAL);
mainLv = new ListView(context);
//listFileAt(Environment.getExternalStorageDirectory().getPath());
mainLv.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> p1, View p2, int p3, long p4)
{
// TODO: Implement this method
File mainFile = new File(p1.getItemAtPosition(p3).toString());
String name = mainFile.getName();
//Toast.makeText(MainActivity.this, name, Toast.LENGTH_LONG).show();
if(name.equals(".. ")){
parentDir();
}
else{
listFileAt(mainFile.getAbsolutePath());
}
}
});
mainLv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
@Override
public boolean onItemLongClick(AdapterView<?> p1, View p2, int p3, long p4)
{
// TODO: Implement this method
File mainFile = new File(p1.getItemAtPosition(p3).toString());
String name = mainFile.getName();
//Toast.makeText(MainActivity.this, name, Toast.LENGTH_LONG).show();
if(mainFile.isFile()){
String extension = getExtension(mainFile.getAbsolutePath());
listener.onFileLongClick(mainFile, mainFile.getAbsolutePath(), name, extension);
return true;
}
return false;
}
});
addView(mainLv, layParam);
}
public void setFileSelectedListener(MFileSelectedListener listener)
{
this.listener = listener;
}
public void listFileAt(final String path)
{
try{
final File mainPath = new File(path);
if(mainPath.exists()){
if(mainPath.isDirectory()){
if(!lockedHome){
homePath = path;
lockedHome = true;
}
fullPath = path;
File[] listFile = mainPath.listFiles();
MFileListAdapter fileAdapter = new MFileListAdapter(context);
if(!path.equals(homePath)){
//fileAdapter.add(new File(path, "Path=\""+path+"\".noEquals(homePath=\""+homePath+"\")"));
fileAdapter.add(new File(path, ".. "));
}
if(listFile.length != 0){
Arrays.sort(listFile, new MSortFileName());
for(File file : listFile){
fileAdapter.add(file);
}
}
mainLv.setAdapter(fileAdapter);
build.setTitle(new File(path).getName());
}
else{
String name = mainPath.getName();
String extension = getExtension(path);
listener.onFileSelected(mainPath, path, name, extension);
}
}
else{
Toast.makeText(context, "This folder (or file) doesn't exist", Toast.LENGTH_SHORT).show();
refreshPath();
}
}
catch(Exception e){
/*
new AlertDialog.Builder(context)
.setTitle("Error")
.setMessage(Log.getStackTraceString(e))
.setPositiveButton("OK", null)
.show();
*/
}
}
public static String getExtension(String path)
{
return getExtension(new File(path));
}
public static String getExtension(File file)
{
return file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf("."));
}
public String getFullPath()
{
return fullPath;
}
public void refreshPath()
{
listFileAt(getFullPath());
}
public void parentDir()
{
File pathFile = new File(fullPath);
if(!pathFile.getAbsolutePath().equals(Environment.getExternalStorageDirectory().getAbsolutePath())){
listFileAt(pathFile.getParent());
}
}
}
@@ -0,0 +1,9 @@
package com.kdt.filermod;
import java.io.File;
public interface MFileSelectedListener
{
public void onFileSelected(File file, String path, String nane, String extension);
public void onFileLongClick(File file, String path, String nane, String extension);
}
@@ -0,0 +1,13 @@
package com.kdt.filermod;
import java.io.*;
import java.util.*;
public class MSortFileName implements Comparator<File>
{
@Override
public int compare(File f1, File f2) {
return f1.getName().compareToIgnoreCase(f2.getName());
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,106 @@
package com.kdt.mcgui;
import android.content.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.util.*;
import android.view.*;
import android.widget.*;
import android.view.View.*;
public class MineButton extends Button
{
private ColorDrawable left = new ColorDrawable(Color.parseColor("#80000000"));
private ColorDrawable top = new ColorDrawable(Color.parseColor("#64FC20"));
private ColorDrawable right = new ColorDrawable(Color.parseColor("#40000000"));
private ColorDrawable bottom = new ColorDrawable(Color.parseColor("#80000000"));
private ColorDrawable bgNormal = new ColorDrawable(Color.parseColor("#36b030"));
private ColorDrawable leftFocus = new ColorDrawable(Color.parseColor("#C2000000"));
private ColorDrawable topFocus = new ColorDrawable(Color.parseColor("#80313131"));
private ColorDrawable rightFocus = new ColorDrawable(Color.parseColor("#C2000000"));
private ColorDrawable bottomFocus = new ColorDrawable(Color.parseColor("#C2000000"));
private ColorDrawable bgFocus = new ColorDrawable(Color.parseColor("#313131"));
private boolean isUp = true;
private Drawable[] DrawableArray = new Drawable[]{
top,
left,
right,
bottom,
bgNormal
};
private Drawable[] DrawableArrayFocus = new Drawable[]{
topFocus,
leftFocus,
rightFocus,
bottomFocus,
bgFocus
};
private LayerDrawable layerdrawable, layerdrawablefocus;
public MineButton(Context ctx)
{
super(ctx);
init();
}
public MineButton(Context ctx, AttributeSet attrs)
{
super(ctx, attrs);
init();
}
public void init()
{
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
layerdrawable = new LayerDrawable(DrawableArray);
layerdrawable.setLayerInset(0, 0, 0, 0, 0); // top
layerdrawable.setLayerInset(1, 0, 8, getWidth() - 8,0); // left
layerdrawable.setLayerInset(2, getWidth() - 8, 8, 0, 0); // right
layerdrawable.setLayerInset(3, 0, getHeight() - 8, 0, 0); // bottom
layerdrawable.setLayerInset(4, 8, 8, 8, 8); // bg
layerdrawablefocus = new LayerDrawable(DrawableArrayFocus);
layerdrawablefocus.setLayerInset(0, 0, 0, 0, 0); // top
layerdrawablefocus.setLayerInset(1, 0, 8, getWidth() - 8,0); // left
layerdrawablefocus.setLayerInset(2, getWidth() - 8, 8, 0, 0); // right
layerdrawablefocus.setLayerInset(3, 0, getHeight() - 8, 0, 0); // bottom
layerdrawablefocus.setLayerInset(4, 8, 8, 8, 8); // bg
setBackgroundDrawable(layerdrawable);
setTextColor(Color.WHITE);
setPadding(10, 10, 10, 10);
//setOnTouchListener(null);
}
});
setTypeface(Typeface.createFromAsset(getContext().getAssets(), "font/NotoSans-Bold.ttf"));
}
@Override
public void setEnabled(boolean enabled)
{
super.setEnabled(enabled);
setBackgroundDrawable(enabled ? layerdrawable : layerdrawablefocus);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
if ((event.getAction() == event.ACTION_UP) && !isUp && isEnabled()) {
setBackgroundDrawable(layerdrawable);
isUp = true;
} else if (event.getAction() == event.ACTION_DOWN && isUp) {
setBackgroundDrawable(layerdrawablefocus);
isUp = false;
}
return super.onTouchEvent(event);
}
}
@@ -0,0 +1,27 @@
package com.kdt.mcgui;
import android.content.*;
import android.util.*;
import android.widget.*;
import net.kdt.pojavlaunch.*;
public class MineEditText extends EditText
{
public MineEditText(Context ctx)
{
super(ctx);
init();
}
public MineEditText(Context ctx, AttributeSet attrs)
{
super(ctx, attrs);
init();
}
public void init()
{
setBackgroundResource(R.drawable.border_edittext);
setPadding(5, 5, 5, 5);
}
}
@@ -0,0 +1,135 @@
package com.kdt.mcgui.app;
import android.app.*;
import android.content.pm.*;
import android.view.*;
import android.widget.*;
import net.kdt.pojavlaunch.*;
import android.os.*;
import android.support.v4.app.*;
import android.support.v7.app.*;
public class MineActivity extends AppCompatActivity implements View.OnClickListener
{
private int topId = 150001;
private boolean showBeforeView = true;
private FontChanger fontChanger;
private ImageButton menu;
private LinearLayout content, undertop;
private LayoutInflater li;
public ViewGroup replaceFonts(ViewGroup viewTree)
{
if (fontChanger == null) fontChanger = new FontChanger(getAssets(), "font/NotoSans-Bold.ttf");
return fontChanger.replaceFonts(viewTree);
}
public View replaceFont(TextView view)
{
if (fontChanger == null) fontChanger = new FontChanger(getAssets(), "font/NotoSans-Bold.ttf");
return fontChanger.replaceFont(view);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mcUIInit();
}
protected void onCreate(Bundle savedInstanceState, boolean showBeforeView)
{
super.onCreate(savedInstanceState);
this.showBeforeView = showBeforeView;
if (showBeforeView) {
mcUIInit();
}
}
private void mcUIInit() {
RelativeLayout root = new RelativeLayout(this);
LinearLayout top = new LinearLayout(this);
top.setId(topId);
content = new LinearLayout(this);
RelativeLayout btm = new RelativeLayout(this);
li = LayoutInflater.from(this);
li.inflate(R.layout.top_bar, top, true);
li.inflate(R.layout.bottom_bar, btm, true);
replaceFonts(btm);
replaceFont((TextView) top.findViewById(R.id.topbar_language_text));
RelativeLayout.LayoutParams conLay = new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
conLay.addRule(root.BELOW, topId);
conLay.bottomMargin = 66;
content.setLayoutParams(conLay);
root.addView(top, new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
root.addView(content);
root.addView(btm);
super.setContentView(root);
TextView ver = (TextView) findViewById(R.id.bottombar_version_view);
menu = (ImageButton) findViewById(R.id.topbar_navmenu_icon);
setMenuVisible(false);
undertop = (LinearLayout) findViewById(R.id.topbar_undertop_view);
try {
ver.setText(getPackageManager().getPackageInfo(getPackageName(), 0).versionName);
} catch (PackageManager.NameNotFoundException e) {} // Never happend!
setClick(R.id.topbar_help_text);
setClick(R.id.topbar_logo);
setClick(R.id.bottombar_author_logo);
}
@Override
public void setContentView(int resource)
{
if (!showBeforeView) {
mcUIInit();
}
li.inflate(resource, content, true);
replaceFonts(content);
}
@Override
public void onClick(View view)
{
switch (view.getId()) {
case R.id.topbar_help_text: Tools.openURL(this, "https://www.minecraft.net/help");
break;
case R.id.topbar_logo: Tools.openURL(this, "https://www.minecraft.net");
break;
case R.id.bottombar_author_logo: Tools.openURL(this, "https://mojang.com");
break;
}
}
public void setUndertopView(View view) {
if (undertop.getChildCount() > 0) {
undertop.removeAllViews();
}
undertop.addView(view);
}
public void setMenuVisible(boolean value) {
menu.setVisibility(value ? View.VISIBLE : View.GONE);
}
public void setClick(int id) {
findViewById(id).setOnClickListener(this);
}
}
@@ -0,0 +1,7 @@
package com.kdt.mojangauth;
public interface LoginListener
{
public void onBeforeLogin();
public void onLoginDone(String[] result);
}
@@ -0,0 +1,71 @@
package com.kdt.mojangauth;
import android.os.*;
import com.kdt.mojangauth.yggdrasil.*;
import java.io.*;
import java.util.*;
import net.kdt.pojavlaunch.*;
public class LoginTask extends AsyncTask<String, Void, String[]>
{
private YggdrasilAuthenticator authenticator = new YggdrasilAuthenticator();
//private String TAG = "MojangAuth-login";
private LoginListener listener;
public LoginTask setLoginListener(LoginListener listener)
{
this.listener = listener;
return this;
}
private UUID getRandomUUID()
{
return UUID.randomUUID();
}
@Override
protected void onPreExecute()
{
listener.onBeforeLogin();
super.onPreExecute();
}
@Override
protected String[] doInBackground(String[] args)
{
ArrayList<String> str = new ArrayList<String>();
str.add("ERROR");
try{
try{
AuthenticateResponse response = authenticator.authenticate(args[0], args[1], getRandomUUID());
if(response.selectedProfile == null){
str.add("Can't login a demo account!\n");
}
else{
if(new File(Tools.mpProfiles + "/" + response.selectedProfile.name).exists()){
str.add("This account already exist!\n");
}
else{
str.add(response.accessToken); // Access token
str.add(response.clientToken.toString()); // Client token
str.add(response.selectedProfile.id); // Profile ID
str.add(response.selectedProfile.name); // Username
str.set(0, "NORMAL");
}
}
}
//MainActivity.updateStatus(804);
catch(Throwable e){
str.add(e.getMessage());
}
}
catch(Exception e){
str.add(e.getMessage());
}
return str.toArray(new String[0]);
}
@Override
protected void onPostExecute(String[] result)
{
listener.onLoginDone(result);
super.onPostExecute(result);
}
}
@@ -0,0 +1,7 @@
package com.kdt.mojangauth;
public interface RefreshListener
{
public void onFailed(Throwable e);
public void onSuccess();
}
@@ -0,0 +1,66 @@
package com.kdt.mojangauth;
import android.content.*;
import android.os.*;
import com.google.gson.*;
import java.util.*;
import net.kdt.pojavlaunch.*;
import com.kdt.mojangauth.yggdrasil.*;
import android.app.*;
public class RefreshTokenTask extends AsyncTask<String, Void, Throwable> {
private YggdrasilAuthenticator authenticator = new YggdrasilAuthenticator();
//private Gson gson = new Gson();
private RefreshListener listener;
private MCProfile.Builder profilePath;
private Context ctx;
private ProgressDialog build;
@Override
public RefreshTokenTask(Context ctx, RefreshListener listener) {
this.ctx = ctx;
this.listener = listener;
}
@Override
public void onPreExecute() {
build = new ProgressDialog(ctx);
build.setMessage("Refreshing");
build.setProgressStyle(ProgressDialog.STYLE_SPINNER);
build.setCancelable(false);
build.show();
}
@Override
public Throwable doInBackground(String... args) {
try {
this.profilePath = MCProfile.load(args[0]);
RefreshResponse response = this.authenticator.refresh(profilePath.getAccessToken(), UUID.fromString(profilePath.getClientID()));
if (response == null) {
throw new NullPointerException("Response is null?");
}
if (response.selectedProfile == null) {
throw new IllegalArgumentException("Can't refresh a demo account!");
}
profilePath.setClientID(response.clientToken.toString());
profilePath.setAccessToken(response.accessToken);
profilePath.setUsername(response.selectedProfile.name);
profilePath.setProfileID(response.selectedProfile.id);
MCProfile.build(profilePath);
return null;
} catch (Throwable e) {
return e;
}
}
@Override
public void onPostExecute(Throwable result) {
build.dismiss();
if (result == null) {
listener.onSuccess();
} else {
listener.onFailed(result);
}
}
}
@@ -0,0 +1,24 @@
package com.kdt.mojangauth.yggdrasil;
import java.util.UUID;
public class AuthenticateRequest {
public AgentInfo agent = new AgentInfo();
public UUID clientToken;
public String password;
public String username;
public static class AgentInfo {
public String name;
public int version;
}
public AuthenticateRequest(String username, String password, UUID clientToken, String clientName, int clientVersion) {
this.username = username;
this.password = password;
this.clientToken = clientToken;
this.agent.name = clientName;
this.agent.version = clientVersion;
}
}
@@ -0,0 +1,11 @@
package com.kdt.mojangauth.yggdrasil;
import java.util.UUID;
public class AuthenticateResponse {
public String accessToken;
public Profile[] availableProfiles;
public UUID clientToken;
public Profile selectedProfile;
}
@@ -0,0 +1,8 @@
package com.kdt.mojangauth.yggdrasil;
public class ErrorResponse {
public String cause;
public String error;
public String errorMessage;
}
@@ -0,0 +1,8 @@
package com.kdt.mojangauth.yggdrasil;
public class Profile {
public String id;
public boolean legacy;
public String name;
}
@@ -0,0 +1,14 @@
package com.kdt.mojangauth.yggdrasil;
import java.util.UUID;
public class RefreshRequest {
public String accessToken;
public UUID clientToken;
public RefreshRequest(String accessToken, UUID clientToken) {
this.accessToken = accessToken;
this.clientToken = clientToken;
}
}
@@ -0,0 +1,10 @@
package com.kdt.mojangauth.yggdrasil;
import java.util.UUID;
public class RefreshResponse {
public String accessToken;
public UUID clientToken;
public Profile selectedProfile;
}
@@ -0,0 +1,99 @@
package com.kdt.mojangauth.yggdrasil;
import android.util.*;
import com.google.gson.*;
import java.io.*;
import java.net.*;
import java.nio.charset.*;
import java.util.*;
public class YggdrasilAuthenticator {
private static final String API_URL = "https://authserver.mojang.com/";
private String clientName = "Minecraft";
private int clientVersion = 1;
private Gson gson = new Gson();
private <T> T makeRequest(String endpoint, Object inputObject, Class<T> responseClass) throws IOException, Throwable {
Throwable th;
InputStream is = null;
byte[] buf = new byte[16384];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String requestJson = this.gson.toJson(inputObject);
try {
URL url = new URL(API_URL + endpoint);
OutputStream os;
try {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("User-Agent", "Minecraft");
conn.setDoInput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/json");
conn.connect();
os = null;
os = conn.getOutputStream();
os.write(requestJson.getBytes(Charset.forName("UTF-8")));
if (os != null) {
os.close();
}
int statusCode = conn.getResponseCode();
if (statusCode != 200) {
is = conn.getErrorStream();
} else {
is = conn.getInputStream();
}
pipe(is, bos, buf);
if (is != null) {
try {
is.close();
} catch (Exception e) {
throw e;
}
}
String outString = new String(bos.toByteArray(), Charset.forName("UTF-8"));
if (statusCode == 200){
Log.i("Result", "Login successful");
return this.gson.fromJson(outString, responseClass);
}
throw new RuntimeException("Invalid username or password");
} catch (UnknownHostException e) {
throw new RuntimeException("Can't connect to the server");
} catch (Throwable th2) {
th = th2;
if (is != null) {
try {
is.close();
} catch (Exception e2) {
throw e2;
}
}
throw th;
}
} catch (Throwable th3) {
th = th3;
if (is != null) {
is.close();
}
throw th;
}
}
public AuthenticateResponse authenticate(String username, String password, UUID clientId) throws IOException, Throwable {
return (AuthenticateResponse) makeRequest("authenticate", new AuthenticateRequest(username, password, clientId, this.clientName, this.clientVersion), AuthenticateResponse.class);
}
public RefreshResponse refresh(String authToken, UUID clientId) throws IOException, Throwable {
return (RefreshResponse) makeRequest("refresh", new RefreshRequest(authToken, clientId), RefreshResponse.class);
}
private void pipe(InputStream is, OutputStream out, byte[] buf) throws IOException {
while (true) {
int amt = is.read(buf);
if (amt >= 0) {
out.write(buf, 0, amt);
} else {
return;
}
}
}
}
@@ -0,0 +1,55 @@
package com.kdtapi.mclup;
import android.content.*;
import android.os.*;
import android.util.*;
import android.widget.*;
import java.io.*;
import net.kdt.pojavlaunch.*;
public abstract class UpContext
{
public abstract void onCreate() throws Exception;
public abstract void onFinish();
public abstract void onErrorw(String message);
private UpdateAppActivity activity;
public UpContext(UpdateAppActivity activity)
{
this.activity = activity;
}
public Context getContext()
{
return getUpActivity();
}
public UpdateAppActivity getUpActivity()
{
return activity;
}
public void onRun()
{
new AsyncTask<Void, Void, Void>(){
@Override
protected Void doInBackground(Void[] p1)
{
try{
onCreate();
onFinish();
new File(Tools.worksDir + "/installer.jar").delete();
}
catch(Exception e){
onErrorw(Log.getStackTraceString(e));
}
return null;
}
}.execute();
}
public ProgressBar getProgressBar()
{
return activity.getProgressBar();
}
public void log(String message)
{
activity.putLog(message);
}
}
+570
View File
@@ -0,0 +1,570 @@
/*
* Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package java.applet;
import java.awt.*;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.Hashtable;
import java.util.Locale;
import javax.accessibility.*;
/**
* An applet is a small program that is intended not to be run on
* its own, but rather to be embedded inside another application.
* <p>
* The <code>Applet</code> class must be the superclass of any
* applet that is to be embedded in a Web page or viewed by the Java
* Applet Viewer. The <code>Applet</code> class provides a standard
* interface between applets and their environment.
*
* @author Arthur van Hoff
* @author Chris Warth
* @since JDK1.0
*/
public class Applet extends Panel
{
/**
* Constructs a new Applet.
* <p>
* Note: Many methods in <code>java.applet.Applet</code>
* may be invoked by the applet only after the applet is
* fully constructed; applet should avoid calling methods
* in <code>java.applet.Applet</code> in the constructor.
*
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
* @since 1.4
*/
public Applet() throws HeadlessException {
if (GraphicsEnvironment.isHeadless()) {
throw new HeadlessException();
}
}
/**
* Applets can be serialized but the following conventions MUST be followed:
*
* Before Serialization:
* An applet must be in STOPPED state.
*
* After Deserialization:
* The applet will be restored in STOPPED state (and most clients will
* likely move it into RUNNING state).
* The stub field will be restored by the reader.
*/
transient private AppletStub stub;
/* version ID for serialized form. */
private static final long serialVersionUID = -5836846270535785031L;
/**
* Read an applet from an object input stream.
* @exception HeadlessException if
* <code>GraphicsEnvironment.isHeadless()</code> returns
* <code>true</code>
* @serial
* @see java.awt.GraphicsEnvironment#isHeadless
* @since 1.4
*/
private void readObject(ObjectInputStream s)
throws ClassNotFoundException, IOException, HeadlessException {
if (GraphicsEnvironment.isHeadless()) {
throw new HeadlessException();
}
s.defaultReadObject();
}
/**
* Sets this applet's stub. This is done automatically by the system.
* <p>If there is a security manager, its <code> checkPermission </code>
* method is called with the
* <code>AWTPermission("setAppletStub")</code>
* permission if a stub has already been set.
* @param stub the new stub.
* @exception SecurityException if the caller cannot set the stub
*/
public final void setStub(AppletStub stub) {
this.stub = stub;
}
/**
* Determines if this applet is active. An applet is marked active
* just before its <code>start</code> method is called. It becomes
* inactive just before its <code>stop</code> method is called.
*
* @return <code>true</code> if the applet is active;
* <code>false</code> otherwise.
* @see java.applet.Applet#start()
* @see java.applet.Applet#stop()
*/
public boolean isActive() {
if (stub != null) {
return stub.isActive();
} else { // If stub field not filled in, applet never active
return false;
}
}
/**
* Gets the URL of the document in which this applet is embedded.
* For example, suppose an applet is contained
* within the document:
* <blockquote><pre>
* http://java.sun.com/products/jdk/1.2/index.html
* </pre></blockquote>
* The document base is:
* <blockquote><pre>
* http://java.sun.com/products/jdk/1.2/index.html
* </pre></blockquote>
*
* @return the {@link java.net.URL} of the document that contains this
* applet.
* @see java.applet.Applet#getCodeBase()
*/
public URL getDocumentBase() {
return stub.getDocumentBase();
}
/**
* Gets the base URL. This is the URL of the directory which contains this applet.
*
* @return the base {@link java.net.URL} of
* the directory which contains this applet.
* @see java.applet.Applet#getDocumentBase()
*/
public URL getCodeBase() {
return stub.getCodeBase();
}
/**
* Returns the value of the named parameter in the HTML tag. For
* example, if this applet is specified as
* <blockquote><pre>
* &lt;applet code="Clock" width=50 height=50&gt;
* &lt;param name=Color value="blue"&gt;
* &lt;/applet&gt;
* </pre></blockquote>
* <p>
* then a call to <code>getParameter("Color")</code> returns the
* value <code>"blue"</code>.
* <p>
* The <code>name</code> argument is case insensitive.
*
* @param name a parameter name.
* @return the value of the named parameter,
* or <code>null</code> if not set.
*/
public String getParameter(String name) {
return stub.getParameter(name);
}
/**
* Determines this applet's context, which allows the applet to
* query and affect the environment in which it runs.
* <p>
* This environment of an applet represents the document that
* contains the applet.
*
* @return the applet's context.
*/
public AppletContext getAppletContext() {
return stub.getAppletContext();
}
/**
* Requests that this applet be resized.
*
* @param width the new requested width for the applet.
* @param height the new requested height for the applet.
*/
public void resize(int width, int height) {
}
/**
* Requests that this applet be resized.
*
* @param d an object giving the new width and height.
*/
public void resize(Dimension d) {
}
/**
* Indicates if this container is a validate root.
* <p>
* {@code Applet} objects are the validate roots, and, therefore, they
* override this method to return {@code true}.
*
* @return {@code true}
* @since 1.7
* @see java.awt.Container#isValidateRoot
*/
public boolean isValidateRoot() {
return true;
}
/**
* Requests that the argument string be displayed in the
* "status window". Many browsers and applet viewers
* provide such a window, where the application can inform users of
* its current state.
*
* @param msg a string to display in the status window.
*/
public void showStatus(String msg) {
getAppletContext().showStatus(msg);
}
/**
* Returns an <code>Image</code> object that can then be painted on
* the screen. The <code>url</code> that is passed as an argument
* must specify an absolute URL.
* <p>
* This method always returns immediately, whether or not the image
* exists. When this applet attempts to draw the image on the screen,
* the data will be loaded. The graphics primitives that draw the
* image will incrementally paint on the screen.
*
* @param url an absolute URL giving the location of the image.
* @return the image at the specified URL.
* @see java.awt.Image
*/
public Image getImage(URL url) {
return getAppletContext().getImage(url);
}
/**
* Returns an <code>Image</code> object that can then be painted on
* the screen. The <code>url</code> argument must specify an absolute
* URL. The <code>name</code> argument is a specifier that is
* relative to the <code>url</code> argument.
* <p>
* This method always returns immediately, whether or not the image
* exists. When this applet attempts to draw the image on the screen,
* the data will be loaded. The graphics primitives that draw the
* image will incrementally paint on the screen.
*
* @param url an absolute URL giving the base location of the image.
* @param name the location of the image, relative to the
* <code>url</code> argument.
* @return the image at the specified URL.
* @see java.awt.Image
*/
public Image getImage(URL url, String name) {
try {
return getImage(new URL(url, name));
} catch (MalformedURLException e) {
return null;
}
}
/**
* Get an audio clip from the given URL.
*
* @param url points to the audio clip
* @return the audio clip at the specified URL.
*
* @since 1.2
*/
public final static AudioClip newAudioClip(URL url) {
return new sun.applet.AppletAudioClip(url);
}
/**
* Returns the <code>AudioClip</code> object specified by the
* <code>URL</code> argument.
* <p>
* This method always returns immediately, whether or not the audio
* clip exists. When this applet attempts to play the audio clip, the
* data will be loaded.
*
* @param url an absolute URL giving the location of the audio clip.
* @return the audio clip at the specified URL.
* @see java.applet.AudioClip
*/
public AudioClip getAudioClip(URL url) {
return getAppletContext().getAudioClip(url);
}
/**
* Returns the <code>AudioClip</code> object specified by the
* <code>URL</code> and <code>name</code> arguments.
* <p>
* This method always returns immediately, whether or not the audio
* clip exists. When this applet attempts to play the audio clip, the
* data will be loaded.
*
* @param url an absolute URL giving the base location of the
* audio clip.
* @param name the location of the audio clip, relative to the
* <code>url</code> argument.
* @return the audio clip at the specified URL.
* @see java.applet.AudioClip
*/
public AudioClip getAudioClip(URL url, String name) {
try {
return getAudioClip(new URL(url, name));
} catch (MalformedURLException e) {
return null;
}
}
/**
* Returns information about this applet. An applet should override
* this method to return a <code>String</code> containing information
* about the author, version, and copyright of the applet.
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class returns <code>null</code>.
*
* @return a string containing information about the author, version, and
* copyright of the applet.
*/
public String getAppletInfo() {
return "This Applet has made from scratch and some source.";
}
/**
* Gets the locale of the applet. It allows the applet
* to maintain its own locale separated from the locale
* of the browser or appletviewer.
*
* @return the locale of the applet; if no locale has
* been set, the default locale is returned.
* @since JDK1.1
*/
public Locale getLocale() {
return Locale.getDefault();
}
/**
* Returns information about the parameters that are understood by
* this applet. An applet should override this method to return an
* array of <code>Strings</code> describing these parameters.
* <p>
* Each element of the array should be a set of three
* <code>Strings</code> containing the name, the type, and a
* description. For example:
* <p><blockquote><pre>
* String pinfo[][] = {
* {"fps", "1-10", "frames per second"},
* {"repeat", "boolean", "repeat image loop"},
* {"imgs", "url", "images directory"}
* };
* </pre></blockquote>
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class returns <code>null</code>.
*
* @return an array describing the parameters this applet looks for.
*/
public String[][] getParameterInfo() {
return null;
}
/**
* Plays the audio clip at the specified absolute URL. Nothing
* happens if the audio clip cannot be found.
*
* @param url an absolute URL giving the location of the audio clip.
*/
public void play(URL url) {
AudioClip clip = getAudioClip(url);
if (clip != null) {
clip.play();
}
}
/**
* Plays the audio clip given the URL and a specifier that is
* relative to it. Nothing happens if the audio clip cannot be found.
*
* @param url an absolute URL giving the base location of the
* audio clip.
* @param name the location of the audio clip, relative to the
* <code>url</code> argument.
*/
public void play(URL url, String name) {
AudioClip clip = getAudioClip(url, name);
if (clip != null) {
clip.play();
}
}
/**
* Called by the browser or applet viewer to inform
* this applet that it has been loaded into the system. It is always
* called before the first time that the <code>start</code> method is
* called.
* <p>
* A subclass of <code>Applet</code> should override this method if
* it has initialization to perform. For example, an applet with
* threads would use the <code>init</code> method to create the
* threads and the <code>destroy</code> method to kill them.
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class does nothing.
*
* @see java.applet.Applet#destroy()
* @see java.applet.Applet#start()
* @see java.applet.Applet#stop()
*/
public void init() {
}
/**
* Called by the browser or applet viewer to inform
* this applet that it should start its execution. It is called after
* the <code>init</code> method and each time the applet is revisited
* in a Web page.
* <p>
* A subclass of <code>Applet</code> should override this method if
* it has any operation that it wants to perform each time the Web
* page containing it is visited. For example, an applet with
* animation might want to use the <code>start</code> method to
* resume animation, and the <code>stop</code> method to suspend the
* animation.
* <p>
* Note: some methods, such as <code>getLocationOnScreen</code>, can only
* provide meaningful results if the applet is showing. Because
* <code>isShowing</code> returns <code>false</code> when the applet's
* <code>start</code> is first called, methods requiring
* <code>isShowing</code> to return <code>true</code> should be called from
* a <code>ComponentListener</code>.
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class does nothing.
*
* @see java.applet.Applet#destroy()
* @see java.applet.Applet#init()
* @see java.applet.Applet#stop()
* @see java.awt.Component#isShowing()
* @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
*/
public void start() {
}
/**
* Called by the browser or applet viewer to inform
* this applet that it should stop its execution. It is called when
* the Web page that contains this applet has been replaced by
* another page, and also just before the applet is to be destroyed.
* <p>
* A subclass of <code>Applet</code> should override this method if
* it has any operation that it wants to perform each time the Web
* page containing it is no longer visible. For example, an applet
* with animation might want to use the <code>start</code> method to
* resume animation, and the <code>stop</code> method to suspend the
* animation.
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class does nothing.
*
* @see java.applet.Applet#destroy()
* @see java.applet.Applet#init()
*/
public void stop() {
}
/**
* Called by the browser or applet viewer to inform
* this applet that it is being reclaimed and that it should destroy
* any resources that it has allocated. The <code>stop</code> method
* will always be called before <code>destroy</code>.
* <p>
* A subclass of <code>Applet</code> should override this method if
* it has any operation that it wants to perform before it is
* destroyed. For example, an applet with threads would use the
* <code>init</code> method to create the threads and the
* <code>destroy</code> method to kill them.
* <p>
* The implementation of this method provided by the
* <code>Applet</code> class does nothing.
*
* @see java.applet.Applet#init()
* @see java.applet.Applet#start()
* @see java.applet.Applet#stop()
*/
public void destroy() {
}
//
// Accessibility support
//
//AccessibleContext accessibleContext = null;
/**
* Gets the AccessibleContext associated with this Applet.
* For applets, the AccessibleContext takes the form of an
* AccessibleApplet.
* A new AccessibleApplet instance is created if necessary.
*
* @return an AccessibleApplet that serves as the
* AccessibleContext of this Applet
* @since 1.3
*/
/*
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleApplet();
}
return accessibleContext;
}
*/
/**
* This class implements accessibility support for the
* <code>Applet</code> class. It provides an implementation of the
* Java Accessibility API appropriate to applet user-interface elements.
* @since 1.3
*/
protected class AccessibleApplet {
private static final long serialVersionUID = 8127374778187708896L;
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
*/
/**
* Get the state of this object.
*
* @return an instance of AccessibleStateSet containing the current
* state set of the object
* @see AccessibleState
*/
}
}
@@ -0,0 +1,193 @@
/*
* Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package java.applet;
import java.awt.Image;
import java.awt.Graphics;
import java.net.URL;
import java.util.Enumeration;
import java.io.InputStream;
import java.io.IOException;
import java.util.Iterator;
/**
* This interface corresponds to an applet's environment: the
* document containing the applet and the other applets in the same
* document.
* <p>
* The methods in this interface can be used by an applet to obtain
* information about its environment.
*
* @author Arthur van Hoff
* @since JDK1.0
*/
public interface AppletContext {
/**
* Creates an audio clip.
*
* @param url an absolute URL giving the location of the audio clip.
* @return the audio clip at the specified URL.
*/
AudioClip getAudioClip(URL url);
/**
* Returns an <code>Image</code> object that can then be painted on
* the screen. The <code>url</code> argument<code> </code>that is
* passed as an argument must specify an absolute URL.
* <p>
* This method always returns immediately, whether or not the image
* exists. When the applet attempts to draw the image on the screen,
* the data will be loaded. The graphics primitives that draw the
* image will incrementally paint on the screen.
*
* @param url an absolute URL giving the location of the image.
* @return the image at the specified URL.
* @see java.awt.Image
*/
Image getImage(URL url);
/**
* Finds and returns the applet in the document represented by this
* applet context with the given name. The name can be set in the
* HTML tag by setting the <code>name</code> attribute.
*
* @param name an applet name.
* @return the applet with the given name, or <code>null</code> if
* not found.
*/
Applet getApplet(String name);
/**
* Finds all the applets in the document represented by this applet
* context.
*
* @return an enumeration of all applets in the document represented by
* this applet context.
*/
Enumeration<Applet> getApplets();
/**
* Requests that the browser or applet viewer show the Web page
* indicated by the <code>url</code> argument. The browser or
* applet viewer determines which window or frame to display the
* Web page. This method may be ignored by applet contexts that
* are not browsers.
*
* @param url an absolute URL giving the location of the document.
*/
void showDocument(URL url);
/**
* Requests that the browser or applet viewer show the Web page
* indicated by the <code>url</code> argument. The
* <code>target</code> argument indicates in which HTML frame the
* document is to be displayed.
* The target argument is interpreted as follows:
* <p>
* <center><table border="3" summary="Target arguments and their descriptions">
* <tr><th>Target Argument</th><th>Description</th></tr>
* <tr><td><code>"_self"</code> <td>Show in the window and frame that
* contain the applet.</tr>
* <tr><td><code>"_parent"</code><td>Show in the applet's parent frame. If
* the applet's frame has no parent frame,
* acts the same as "_self".</tr>
* <tr><td><code>"_top"</code> <td>Show in the top-level frame of the applet's
* window. If the applet's frame is the
* top-level frame, acts the same as "_self".</tr>
* <tr><td><code>"_blank"</code> <td>Show in a new, unnamed
* top-level window.</tr>
* <tr><td><i>name</i><td>Show in the frame or window named <i>name</i>. If
* a target named <i>name</i> does not already exist, a
* new top-level window with the specified name is created,
* and the document is shown there.</tr>
* </table> </center>
* <p>
* An applet viewer or browser is free to ignore <code>showDocument</code>.
*
* @param url an absolute URL giving the location of the document.
* @param target a <code>String</code> indicating where to display
* the page.
*/
public void showDocument(URL url, String target);
/**
* Requests that the argument string be displayed in the
* "status window". Many browsers and applet viewers
* provide such a window, where the application can inform users of
* its current state.
*
* @param status a string to display in the status window.
*/
void showStatus(String status);
/**
* Associates the specified stream with the specified key in this
* applet context. If the applet context previously contained a mapping
* for this key, the old value is replaced.
* <p>
* For security reasons, mapping of streams and keys exists for each
* codebase. In other words, applet from one codebase cannot access
* the streams created by an applet from a different codebase
* <p>
* @param key key with which the specified value is to be associated.
* @param stream stream to be associated with the specified key. If this
* parameter is <code>null</code>, the specified key is removed
* in this applet context.
* @throws <code>IOException</code> if the stream size exceeds a certain
* size limit. Size limit is decided by the implementor of this
* interface.
* @since 1.4
*/
public void setStream(String key, InputStream stream)throws IOException;
/**
* Returns the stream to which specified key is associated within this
* applet context. Returns <tt>null</tt> if the applet context contains
* no stream for this key.
* <p>
* For security reasons, mapping of streams and keys exists for each
* codebase. In other words, applet from one codebase cannot access
* the streams created by an applet from a different codebase
* <p>
* @return the stream to which this applet context maps the key
* @param key key whose associated stream is to be returned.
* @since 1.4
*/
public InputStream getStream(String key);
/**
* Finds all the keys of the streams in this applet context.
* <p>
* For security reasons, mapping of streams and keys exists for each
* codebase. In other words, applet from one codebase cannot access
* the streams created by an applet from a different codebase
* <p>
* @return an Iterator of all the names of the streams in this applet
* context.
* @since 1.4
*/
public Iterator<String> getStreamKeys();
}
@@ -0,0 +1,111 @@
/*
* Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package java.applet;
import java.net.URL;
/**
* When an applet is first created, an applet stub is attached to it
* using the applet's <code>setStub</code> method. This stub
* serves as the interface between the applet and the browser
* environment or applet viewer environment in which the application
* is running.
*
* @author Arthur van Hoff
* @see java.applet.Applet#setStub(java.applet.AppletStub)
* @since JDK1.0
*/
public interface AppletStub {
/**
* Determines if the applet is active. An applet is active just
* before its <code>start</code> method is called. It becomes
* inactive just before its <code>stop</code> method is called.
*
* @return <code>true</code> if the applet is active;
* <code>false</code> otherwise.
*/
boolean isActive();
/**
* Gets the URL of the document in which the applet is embedded.
* For example, suppose an applet is contained
* within the document:
* <blockquote><pre>
* http://java.sun.com/products/jdk/1.2/index.html
* </pre></blockquote>
* The document base is:
* <blockquote><pre>
* http://java.sun.com/products/jdk/1.2/index.html
* </pre></blockquote>
*
* @return the {@link java.net.URL} of the document that contains the
* applet.
* @see java.applet.AppletStub#getCodeBase()
*/
URL getDocumentBase();
/**
* Gets the base URL. This is the URL of the directory which contains the applet.
*
* @return the base {@link java.net.URL} of
* the directory which contains the applet.
* @see java.applet.AppletStub#getDocumentBase()
*/
URL getCodeBase();
/**
* Returns the value of the named parameter in the HTML tag. For
* example, if an applet is specified as
* <blockquote><pre>
* &lt;applet code="Clock" width=50 height=50&gt;
* &lt;param name=Color value="blue"&gt;
* &lt;/applet&gt;
* </pre></blockquote>
* <p>
* then a call to <code>getParameter("Color")</code> returns the
* value <code>"blue"</code>.
*
* @param name a parameter name.
* @return the value of the named parameter,
* or <tt>null</tt> if not set.
*/
String getParameter(String name);
/**
* Returns the applet's context.
*
* @return the applet's context.
*/
AppletContext getAppletContext();
/**
* Called when the applet wants to be resized.
*
* @param width the new requested width for the applet.
* @param height the new requested height for the applet.
*/
void appletResize(int width, int height);
}
@@ -0,0 +1,53 @@
/*
* Copyright (c) 1995, 1997, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package java.applet;
/**
* The <code>AudioClip</code> interface is a simple abstraction for
* playing a sound clip. Multiple <code>AudioClip</code> items can be
* playing at the same time, and the resulting sound is mixed
* together to produce a composite.
*
* @author Arthur van Hoff
* @since JDK1.0
*/
public interface AudioClip {
/**
* Starts playing this audio clip. Each time this method is called,
* the clip is restarted from the beginning.
*/
void play();
/**
* Starts playing this audio clip in a loop.
*/
void loop();
/**
* Stops playing this audio clip.
*/
void stop();
}
+49
View File
@@ -0,0 +1,49 @@
/*
* Copyright (c) 1995, 1997, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt;
/**
* Thrown when a serious Abstract Window Toolkit error has occurred.
*
* @author Arthur van Hoff
*/
public class AWTError extends Error {
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -1819846354050686206L;
/**
* Constructs an instance of <code>AWTError</code> with the specified
* detail message.
* @param msg the detail message.
* @since JDK1.0
*/
public AWTError(String msg) {
super(msg);
}
}
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Michael Danilov
* @version $Revision$
*/
package java.awt;
/**
* The AWTException class is used to provide notification and information about
* AWT errors.
*
* @since Android 1.0
*/
public class AWTException extends Exception {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = -1900414231151323879L;
/**
* Instantiates a new AWT exception with the specified message.
*
* @param msg
* the specific message for current exception.
*/
public AWTException(String msg) {
super(msg);
}
}
@@ -0,0 +1,875 @@
/*
* Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt;
import java.util.Hashtable;
/**
* A border layout lays out a container, arranging and resizing
* its components to fit in five regions:
* north, south, east, west, and center.
* Each region may contain no more than one component, and
* is identified by a corresponding constant:
* <code>NORTH</code>, <code>SOUTH</code>, <code>EAST</code>,
* <code>WEST</code>, and <code>CENTER</code>. When adding a
* component to a container with a border layout, use one of these
* five constants, for example:
* <pre>
* Panel p = new Panel();
* p.setLayout(new BorderLayout());
* p.add(new Button("Okay"), BorderLayout.SOUTH);
* </pre>
* As a convenience, <code>BorderLayout</code> interprets the
* absence of a string specification the same as the constant
* <code>CENTER</code>:
* <pre>
* Panel p2 = new Panel();
* p2.setLayout(new BorderLayout());
* p2.add(new TextArea()); // Same as p.add(new TextArea(), BorderLayout.CENTER);
* </pre>
* <p>
* In addition, <code>BorderLayout</code> supports the relative
* positioning constants, <code>PAGE_START</code>, <code>PAGE_END</code>,
* <code>LINE_START</code>, and <code>LINE_END</code>.
* In a container whose <code>ComponentOrientation</code> is set to
* <code>ComponentOrientation.LEFT_TO_RIGHT</code>, these constants map to
* <code>NORTH</code>, <code>SOUTH</code>, <code>WEST</code>, and
* <code>EAST</code>, respectively.
* <p>
* For compatibility with previous releases, <code>BorderLayout</code>
* also includes the relative positioning constants <code>BEFORE_FIRST_LINE</code>,
* <code>AFTER_LAST_LINE</code>, <code>BEFORE_LINE_BEGINS</code> and
* <code>AFTER_LINE_ENDS</code>. These are equivalent to
* <code>PAGE_START</code>, <code>PAGE_END</code>, <code>LINE_START</code>
* and <code>LINE_END</code> respectively. For
* consistency with the relative positioning constants used by other
* components, the latter constants are preferred.
* <p>
* Mixing both absolute and relative positioning constants can lead to
* unpredicable results. If
* you use both types, the relative constants will take precedence.
* For example, if you add components using both the <code>NORTH</code>
* and <code>PAGE_START</code> constants in a container whose
* orientation is <code>LEFT_TO_RIGHT</code>, only the
* <code>PAGE_START</code> will be layed out.
* <p>
* NOTE: Currently (in the Java 2 platform v1.2),
* <code>BorderLayout</code> does not support vertical
* orientations. The <code>isVertical</code> setting on the container's
* <code>ComponentOrientation</code> is not respected.
* <p>
* The components are laid out according to their
* preferred sizes and the constraints of the container's size.
* The <code>NORTH</code> and <code>SOUTH</code> components may
* be stretched horizontally; the <code>EAST</code> and
* <code>WEST</code> components may be stretched vertically;
* the <code>CENTER</code> component may stretch both horizontally
* and vertically to fill any space left over.
* <p>
* Here is an example of five buttons in an applet laid out using
* the <code>BorderLayout</code> layout manager:
* <p>
* <img src="doc-files/BorderLayout-1.gif"
* alt="Diagram of an applet demonstrating BorderLayout.
* Each section of the BorderLayout contains a Button corresponding to its position in the layout, one of:
* North, West, Center, East, or South."
* ALIGN=center HSPACE=10 VSPACE=7>
* <p>
* The code for this applet is as follows:
* <p>
* <hr><blockquote><pre>
* import java.awt.*;
* import java.applet.Applet;
*
* public class buttonDir extends Applet {
* public void init() {
* setLayout(new BorderLayout());
* add(new Button("North"), BorderLayout.NORTH);
* add(new Button("South"), BorderLayout.SOUTH);
* add(new Button("East"), BorderLayout.EAST);
* add(new Button("West"), BorderLayout.WEST);
* add(new Button("Center"), BorderLayout.CENTER);
* }
* }
* </pre></blockquote><hr>
* <p>
* @author Arthur van Hoff
* @see java.awt.Container#add(String, Component)
* @see java.awt.ComponentOrientation
* @since JDK1.0
*/
public class BorderLayout implements LayoutManager2,
java.io.Serializable {
/**
* Constructs a border layout with the horizontal gaps
* between components.
* The horizontal gap is specified by <code>hgap</code>.
*
* @see #getHgap()
* @see #setHgap(int)
*
* @serial
*/
int hgap;
/**
* Constructs a border layout with the vertical gaps
* between components.
* The vertical gap is specified by <code>vgap</code>.
*
* @see #getVgap()
* @see #setVgap(int)
* @serial
*/
int vgap;
/**
* Constant to specify components location to be the
* north portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component north;
/**
* Constant to specify components location to be the
* west portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component west;
/**
* Constant to specify components location to be the
* east portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component east;
/**
* Constant to specify components location to be the
* south portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component south;
/**
* Constant to specify components location to be the
* center portion of the border layout.
* @serial
* @see #getChild(String, boolean)
* @see #addLayoutComponent
* @see #getLayoutAlignmentX
* @see #getLayoutAlignmentY
* @see #removeLayoutComponent
*/
Component center;
/**
*
* A relative positioning constant, that can be used instead of
* north, south, east, west or center.
* mixing the two types of constants can lead to unpredicable results. If
* you use both types, the relative constants will take precedence.
* For example, if you add components using both the <code>NORTH</code>
* and <code>BEFORE_FIRST_LINE</code> constants in a container whose
* orientation is <code>LEFT_TO_RIGHT</code>, only the
* <code>BEFORE_FIRST_LINE</code> will be layed out.
* This will be the same for lastLine, firstItem, lastItem.
* @serial
*/
Component firstLine;
/**
* A relative positioning constant, that can be used instead of
* north, south, east, west or center.
* Please read Description for firstLine.
* @serial
*/
Component lastLine;
/**
* A relative positioning constant, that can be used instead of
* north, south, east, west or center.
* Please read Description for firstLine.
* @serial
*/
Component firstItem;
/**
* A relative positioning constant, that can be used instead of
* north, south, east, west or center.
* Please read Description for firstLine.
* @serial
*/
Component lastItem;
/**
* The north layout constraint (top of container).
*/
public static final String NORTH = "North";
/**
* The south layout constraint (bottom of container).
*/
public static final String SOUTH = "South";
/**
* The east layout constraint (right side of container).
*/
public static final String EAST = "East";
/**
* The west layout constraint (left side of container).
*/
public static final String WEST = "West";
/**
* The center layout constraint (middle of container).
*/
public static final String CENTER = "Center";
/**
* Synonym for PAGE_START. Exists for compatibility with previous
* versions. PAGE_START is preferred.
*
* @see #PAGE_START
* @since 1.2
*/
public static final String BEFORE_FIRST_LINE = "First";
/**
* Synonym for PAGE_END. Exists for compatibility with previous
* versions. PAGE_END is preferred.
*
* @see #PAGE_END
* @since 1.2
*/
public static final String AFTER_LAST_LINE = "Last";
/**
* Synonym for LINE_START. Exists for compatibility with previous
* versions. LINE_START is preferred.
*
* @see #LINE_START
* @since 1.2
*/
public static final String BEFORE_LINE_BEGINS = "Before";
/**
* Synonym for LINE_END. Exists for compatibility with previous
* versions. LINE_END is preferred.
*
* @see #LINE_END
* @since 1.2
*/
public static final String AFTER_LINE_ENDS = "After";
/**
* The component comes before the first line of the layout's content.
* For Western, left-to-right and top-to-bottom orientations, this is
* equivalent to NORTH.
*
* @see java.awt.Component#getComponentOrientation
* @since 1.4
*/
public static final String PAGE_START = BEFORE_FIRST_LINE;
/**
* The component comes after the last line of the layout's content.
* For Western, left-to-right and top-to-bottom orientations, this is
* equivalent to SOUTH.
*
* @see java.awt.Component#getComponentOrientation
* @since 1.4
*/
public static final String PAGE_END = AFTER_LAST_LINE;
/**
* The component goes at the beginning of the line direction for the
* layout. For Western, left-to-right and top-to-bottom orientations,
* this is equivalent to WEST.
*
* @see java.awt.Component#getComponentOrientation
* @since 1.4
*/
public static final String LINE_START = BEFORE_LINE_BEGINS;
/**
* The component goes at the end of the line direction for the
* layout. For Western, left-to-right and top-to-bottom orientations,
* this is equivalent to EAST.
*
* @see java.awt.Component#getComponentOrientation
* @since 1.4
*/
public static final String LINE_END = AFTER_LINE_ENDS;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -8658291919501921765L;
/**
* Constructs a new border layout with
* no gaps between components.
*/
public BorderLayout() {
this(0, 0);
}
/**
* Constructs a border layout with the specified gaps
* between components.
* The horizontal gap is specified by <code>hgap</code>
* and the vertical gap is specified by <code>vgap</code>.
* @param hgap the horizontal gap.
* @param vgap the vertical gap.
*/
public BorderLayout(int hgap, int vgap) {
this.hgap = hgap;
this.vgap = vgap;
}
/**
* Returns the horizontal gap between components.
* @since JDK1.1
*/
public int getHgap() {
return hgap;
}
/**
* Sets the horizontal gap between components.
* @param hgap the horizontal gap between components
* @since JDK1.1
*/
public void setHgap(int hgap) {
this.hgap = hgap;
}
/**
* Returns the vertical gap between components.
* @since JDK1.1
*/
public int getVgap() {
return vgap;
}
/**
* Sets the vertical gap between components.
* @param vgap the vertical gap between components
* @since JDK1.1
*/
public void setVgap(int vgap) {
this.vgap = vgap;
}
/**
* Adds the specified component to the layout, using the specified
* constraint object. For border layouts, the constraint must be
* one of the following constants: <code>NORTH</code>,
* <code>SOUTH</code>, <code>EAST</code>,
* <code>WEST</code>, or <code>CENTER</code>.
* <p>
* Most applications do not call this method directly. This method
* is called when a component is added to a container using the
* <code>Container.add</code> method with the same argument types.
* @param comp the component to be added.
* @param constraints an object that specifies how and where
* the component is added to the layout.
* @see java.awt.Container#add(java.awt.Component, java.lang.Object)
* @exception IllegalArgumentException if the constraint object is not
* a string, or if it not one of the five specified
* constants.
* @since JDK1.1
*/
public void addLayoutComponent(Component comp, Object constraints) {
if ((constraints == null) || (constraints instanceof String)) {
addLayoutComponent((String)constraints, comp);
} else {
throw new IllegalArgumentException("cannot add to layout: constraint must be a string (or null)");
}
}
/**
* @deprecated replaced by <code>addLayoutComponent(Component, Object)</code>.
*/
@Deprecated
public void addLayoutComponent(String name, Component comp) {
/* Special case: treat null the same as "Center". */
if (name == null) {
name = "Center";
}
/* Assign the component to one of the known regions of the layout.
*/
if ("Center".equals(name)) {
center = comp;
} else if ("North".equals(name)) {
north = comp;
} else if ("South".equals(name)) {
south = comp;
} else if ("East".equals(name)) {
east = comp;
} else if ("West".equals(name)) {
west = comp;
} else if (BEFORE_FIRST_LINE.equals(name)) {
firstLine = comp;
} else if (AFTER_LAST_LINE.equals(name)) {
lastLine = comp;
} else if (BEFORE_LINE_BEGINS.equals(name)) {
firstItem = comp;
} else if (AFTER_LINE_ENDS.equals(name)) {
lastItem = comp;
} else {
throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
}
}
/**
* Removes the specified component from this border layout. This
* method is called when a container calls its <code>remove</code> or
* <code>removeAll</code> methods. Most applications do not call this
* method directly.
* @param comp the component to be removed.
* @see java.awt.Container#remove(java.awt.Component)
* @see java.awt.Container#removeAll()
*/
public void removeLayoutComponent(Component comp) {
if (comp == center) {
center = null;
} else if (comp == north) {
north = null;
} else if (comp == south) {
south = null;
} else if (comp == east) {
east = null;
} else if (comp == west) {
west = null;
}
if (comp == firstLine) {
firstLine = null;
} else if (comp == lastLine) {
lastLine = null;
} else if (comp == firstItem) {
firstItem = null;
} else if (comp == lastItem) {
lastItem = null;
}
}
/**
* Gets the component that was added using the given constraint
*
* @param constraints the desired constraint, one of <code>CENTER</code>,
* <code>NORTH</code>, <code>SOUTH</code>,
* <code>WEST</code>, <code>EAST</code>,
* <code>PAGE_START</code>, <code>PAGE_END</code>,
* <code>LINE_START</code>, <code>LINE_END</code>
* @return the component at the given location, or <code>null</code> if
* the location is empty
* @exception IllegalArgumentException if the constraint object is
* not one of the nine specified constants
* @see #addLayoutComponent(java.awt.Component, java.lang.Object)
* @since 1.5
*/
public Component getLayoutComponent(Object constraints) {
if (CENTER.equals(constraints)) {
return center;
} else if (NORTH.equals(constraints)) {
return north;
} else if (SOUTH.equals(constraints)) {
return south;
} else if (WEST.equals(constraints)) {
return west;
} else if (EAST.equals(constraints)) {
return east;
} else if (PAGE_START.equals(constraints)) {
return firstLine;
} else if (PAGE_END.equals(constraints)) {
return lastLine;
} else if (LINE_START.equals(constraints)) {
return firstItem;
} else if (LINE_END.equals(constraints)) {
return lastItem;
} else {
throw new IllegalArgumentException("cannot get component: unknown constraint: " + constraints);
}
}
/**
* Returns the component that corresponds to the given constraint location
* based on the target <code>Container</code>'s component orientation.
* Components added with the relative constraints <code>PAGE_START</code>,
* <code>PAGE_END</code>, <code>LINE_START</code>, and <code>LINE_END</code>
* take precedence over components added with the explicit constraints
* <code>NORTH</code>, <code>SOUTH</code>, <code>WEST</code>, and <code>EAST</code>.
* The <code>Container</code>'s component orientation is used to determine the location of components
* added with <code>LINE_START</code> and <code>LINE_END</code>.
*
* @param constraints the desired absolute position, one of <code>CENTER</code>,
* <code>NORTH</code>, <code>SOUTH</code>,
* <code>EAST</code>, <code>WEST</code>
* @param target the {@code Container} used to obtain
* the constraint location based on the target
* {@code Container}'s component orientation.
* @return the component at the given location, or <code>null</code> if
* the location is empty
* @exception IllegalArgumentException if the constraint object is
* not one of the five specified constants
* @exception NullPointerException if the target parameter is null
* @see #addLayoutComponent(java.awt.Component, java.lang.Object)
* @since 1.5
*/
public Component getLayoutComponent(Container target, Object constraints) {
boolean ltr = target.getComponentOrientation().isLeftToRight();
Component result = null;
if (NORTH.equals(constraints)) {
result = (firstLine != null) ? firstLine : north;
} else if (SOUTH.equals(constraints)) {
result = (lastLine != null) ? lastLine : south;
} else if (WEST.equals(constraints)) {
result = ltr ? firstItem : lastItem;
if (result == null) {
result = west;
}
} else if (EAST.equals(constraints)) {
result = ltr ? lastItem : firstItem;
if (result == null) {
result = east;
}
} else if (CENTER.equals(constraints)) {
result = center;
} else {
throw new IllegalArgumentException("cannot get component: invalid constraint: " + constraints);
}
return result;
}
/**
* Gets the constraints for the specified component
*
* @param comp the component to be queried
* @return the constraint for the specified component,
* or null if component is null or is not present
* in this layout
* @see #addLayoutComponent(java.awt.Component, java.lang.Object)
* @since 1.5
*/
public Object getConstraints(Component comp) {
//fix for 6242148 : API method java.awt.BorderLayout.getConstraints(null) should return null
if (comp == null){
return null;
}
if (comp == center) {
return CENTER;
} else if (comp == north) {
return NORTH;
} else if (comp == south) {
return SOUTH;
} else if (comp == west) {
return WEST;
} else if (comp == east) {
return EAST;
} else if (comp == firstLine) {
return PAGE_START;
} else if (comp == lastLine) {
return PAGE_END;
} else if (comp == firstItem) {
return LINE_START;
} else if (comp == lastItem) {
return LINE_END;
}
return null;
}
/**
* Determines the minimum size of the <code>target</code> container
* using this layout manager.
* <p>
* This method is called when a container calls its
* <code>getMinimumSize</code> method. Most applications do not call
* this method directly.
* @param target the container in which to do the layout.
* @return the minimum dimensions needed to lay out the subcomponents
* of the specified container.
* @see java.awt.Container
* @see java.awt.BorderLayout#preferredLayoutSize
* @see java.awt.Container#getMinimumSize()
*/
public Dimension minimumLayoutSize(Container target) {
Dimension dim = new Dimension(0, 0);
boolean ltr = target.getComponentOrientation().isLeftToRight();
Component c = null;
if ((c=getChild(EAST,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(WEST,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(CENTER,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width += d.width;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(NORTH,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
if ((c=getChild(SOUTH,ltr)) != null) {
Dimension d = c.getMinimumSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right;
dim.height += insets.top + insets.bottom;
return dim;
}
/**
* Determines the preferred size of the <code>target</code>
* container using this layout manager, based on the components
* in the container.
* <p>
* Most applications do not call this method directly. This method
* is called when a container calls its <code>getPreferredSize</code>
* method.
* @param target the container in which to do the layout.
* @return the preferred dimensions to lay out the subcomponents
* of the specified container.
* @see java.awt.Container
* @see java.awt.BorderLayout#minimumLayoutSize
* @see java.awt.Container#getPreferredSize()
*/
public Dimension preferredLayoutSize(Container target) {
Dimension dim = new Dimension(0, 0);
boolean ltr = target.getComponentOrientation().isLeftToRight();
Component c = null;
if ((c=getChild(EAST,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(WEST,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width += d.width + hgap;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(CENTER,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width += d.width;
dim.height = Math.max(d.height, dim.height);
}
if ((c=getChild(NORTH,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
if ((c=getChild(SOUTH,ltr)) != null) {
Dimension d = c.getPreferredSize();
dim.width = Math.max(d.width, dim.width);
dim.height += d.height + vgap;
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right;
dim.height += insets.top + insets.bottom;
return dim;
}
/**
* Returns the maximum dimensions for this layout given the components
* in the specified target container.
* @param target the component which needs to be laid out
* @see Container
* @see #minimumLayoutSize
* @see #preferredLayoutSize
*/
public Dimension maximumLayoutSize(Container target) {
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
/**
* Returns the alignment along the x axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentX(Container parent) {
return 0.5f;
}
/**
* Returns the alignment along the y axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentY(Container parent) {
return 0.5f;
}
/**
* Invalidates the layout, indicating that if the layout manager
* has cached information it should be discarded.
*/
public void invalidateLayout(Container target) {
}
/**
* Lays out the container argument using this border layout.
* <p>
* This method actually reshapes the components in the specified
* container in order to satisfy the constraints of this
* <code>BorderLayout</code> object. The <code>NORTH</code>
* and <code>SOUTH</code> components, if any, are placed at
* the top and bottom of the container, respectively. The
* <code>WEST</code> and <code>EAST</code> components are
* then placed on the left and right, respectively. Finally,
* the <code>CENTER</code> object is placed in any remaining
* space in the middle.
* <p>
* Most applications do not call this method directly. This method
* is called when a container calls its <code>doLayout</code> method.
* @param target the container in which to do the layout.
* @see java.awt.Container
* @see java.awt.Container#doLayout()
*/
public void layoutContainer(Container target) {
Insets insets = target.getInsets();
int top = insets.top;
int bottom = target.getHeight() - insets.bottom;
int left = insets.left;
int right = target.getWidth() - insets.right;
boolean ltr = target.getComponentOrientation().isLeftToRight();
Component c = null;
if ((c=getChild(NORTH,ltr)) != null) {
c.setSize(right - left, c.getHeight());
Dimension d = c.getPreferredSize();
c.setBounds(left, top, right - left, d.height);
top += d.height + vgap;
}
if ((c=getChild(SOUTH,ltr)) != null) {
c.setSize(right - left, c.getHeight());
Dimension d = c.getPreferredSize();
c.setBounds(left, bottom - d.height, right - left, d.height);
bottom -= d.height + vgap;
}
if ((c=getChild(EAST,ltr)) != null) {
c.setSize(c.getWidth(), bottom - top);
Dimension d = c.getPreferredSize();
c.setBounds(right - d.width, top, d.width, bottom - top);
right -= d.width + hgap;
}
if ((c=getChild(WEST,ltr)) != null) {
c.setSize(c.getWidth(), bottom - top);
Dimension d = c.getPreferredSize();
c.setBounds(left, top, d.width, bottom - top);
left += d.width + hgap;
}
if ((c=getChild(CENTER,ltr)) != null) {
c.setBounds(left, top, right - left, bottom - top);
}
}
/**
* Get the component that corresponds to the given constraint location
*
* @param key The desired absolute position,
* either NORTH, SOUTH, EAST, or WEST.
* @param ltr Is the component line direction left-to-right?
*/
private Component getChild(String key, boolean ltr) {
Component result = null;
if (key == NORTH) {
result = (firstLine != null) ? firstLine : north;
}
else if (key == SOUTH) {
result = (lastLine != null) ? lastLine : south;
}
else if (key == WEST) {
result = ltr ? firstItem : lastItem;
if (result == null) {
result = west;
}
}
else if (key == EAST) {
result = ltr ? lastItem : firstItem;
if (result == null) {
result = east;
}
}
else if (key == CENTER) {
result = center;
}
if (result != null && !result.visible) {
result = null;
}
return result;
}
/**
* Returns a string representation of the state of this border layout.
* @return a string representation of this border layout.
*/
public String toString() {
return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + "]";
}
}
+39
View File
@@ -0,0 +1,39 @@
package java.awt;
import java.awt.image.*;
import net.kdt.pojavlaunch.*;
public class Canvas extends Component {
private Graphics mGraphics;
private Dimension mSize;
public Canvas() {
mSize = new Dimension(1280, 720);
mGraphics = new Graphics(new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB));
}
public void setPreferredSize(Dimension dim){
mSize = dim;
}
public void setFocusTraversalKeysEnabled(boolean b) {
System.out.println("java.awt.Canvas.setFocusTraversalKeysEnabled(" + b + ")");
}
public boolean isDisplayable(){
return true;
}
public Graphics getGraphics() {
return mGraphics;
}
public int getWidth() {
return (int) mSize.getWidth();
}
public int getHeight() {
return (int) mSize.getHeight();
}
}
+329
View File
@@ -0,0 +1,329 @@
package java.awt;
import java.io.Serializable;
public class Color implements Serializable {
public static final Color black = new Color(0, 0, 0);
public static final Color blue = new Color(0, 0, 255);
public static final Color cyan = new Color(0, 255, 255);
public static final Color darkGray = new Color(64, 64, 64);
public static final Color gray = new Color(128, 128, 128);
public static final Color green = new Color(0, 255, 0);
public static final Color lightGray = new Color(192, 192, 192);
public static final Color magenta = new Color(255, 0, 255);
public static final Color orange = new Color(255, 200, 0);
public static final Color pink = new Color(255, 175, 175);
public static final Color red = new Color(255, 0, 0);
private static final long serialVersionUID = 118526816881161077L;
public static final Color white = new Color(255, 255, 255);
public static final Color yellow = new Color(255, 255, 0);
public static final Color BLACK = black;
public static final Color BLUE = blue;
public static final Color CYAN = cyan;
public static final Color DARK_GRAY = darkGray;
public static final Color GRAY = gray;
public static final Color GREEN = green;
public static final Color LIGHT_GRAY = lightGray;
public static final Color MAGENTA = magenta;
private static final int MIN_SCALABLE = 3;
public static final Color ORANGE = orange;
public static final Color PINK = pink;
public static final Color RED = red;
private static final double SCALE_FACTOR = 0.7d;
public static final Color WHITE = white;
public static final Color YELLOW = yellow;
private float falpha;
private float[] frgbvalue;
private float[] fvalue;
int value;
public Color(int rgba, boolean hasAlpha) {
if (hasAlpha) {
this.value = rgba;
} else {
this.value = -16777216 | rgba;
}
}
public Color(int r, int g, int b, int a) {
if ((r & 255) == r && (g & 255) == g && (b & 255) == b && (a & 255) == a) {
this.value = (((g << 8) | b) | (r << 16)) | (a << 24);
return;
}
throw new IllegalArgumentException("Color parameter outside of expected range");
}
public Color(int r, int g, int b) {
if ((r & 255) == r && (g & 255) == g && (b & 255) == b) {
this.value = (((g << 8) | b) | (r << 16)) | -16777216;
return;
}
throw new IllegalArgumentException("Color parameter outside of expected range");
}
public Color(int rgb) {
this.value = -16777216 | rgb;
}
public Color(float r, float g, float b, float a) {
this((int) (((double) (r * 255.0f)) + 0.5d), (int) (((double) (g * 255.0f)) + 0.5d), (int) (((double) (b * 255.0f)) + 0.5d), (int) (((double) (a * 255.0f)) + 0.5d));
this.falpha = a;
this.fvalue = new float[MIN_SCALABLE];
this.fvalue[0] = r;
this.fvalue[1] = g;
this.fvalue[2] = b;
this.frgbvalue = this.fvalue;
}
public Color(float r, float g, float b) {
this(r, g, b, 1.0f);
}
public String toString() {
return getClass().getName() + "[r=" + getRed() + ",g=" + getGreen() + ",b=" + getBlue() + "]";
}
public boolean equals(Object obj) {
if ((obj instanceof Color) && ((Color) obj).value == this.value) {
return true;
}
return false;
}
public Color darker() {
return new Color((int) (((double) getRed()) * SCALE_FACTOR), (int) (((double) getGreen()) * SCALE_FACTOR), (int) (((double) getBlue()) * SCALE_FACTOR));
}
public Color brighter() {
int r = getRed();
int b = getBlue();
int g = getGreen();
if (r == 0 && b == 0 && g == 0) {
return new Color((int) MIN_SCALABLE, (int) MIN_SCALABLE, (int) MIN_SCALABLE);
}
if (r >= MIN_SCALABLE || r == 0) {
r = (int) (((double) r) / SCALE_FACTOR);
if (r > 255) {
r = 255;
}
} else {
r = MIN_SCALABLE;
}
if (b >= MIN_SCALABLE || b == 0) {
b = (int) (((double) b) / SCALE_FACTOR);
if (b > 255) {
b = 255;
}
} else {
b = MIN_SCALABLE;
}
if (g >= MIN_SCALABLE || g == 0) {
g = (int) (((double) g) / SCALE_FACTOR);
if (g > 255) {
g = 255;
}
} else {
g = MIN_SCALABLE;
}
return new Color(r, g, b);
}
public float[] getRGBComponents(float[] components) {
if (components == null) {
components = new float[4];
}
if (this.frgbvalue != null) {
components[MIN_SCALABLE] = this.falpha;
} else {
components[MIN_SCALABLE] = ((float) getAlpha()) / 255.0f;
}
getRGBColorComponents(components);
return components;
}
public float[] getRGBColorComponents(float[] components) {
if (components == null) {
components = new float[MIN_SCALABLE];
}
if (this.frgbvalue != null) {
components[2] = this.frgbvalue[2];
components[1] = this.frgbvalue[1];
components[0] = this.frgbvalue[0];
} else {
components[2] = ((float) getBlue()) / 255.0f;
components[1] = ((float) getGreen()) / 255.0f;
components[0] = ((float) getRed()) / 255.0f;
}
return components;
}
public float[] getComponents(float[] components) {
if (this.fvalue == null) {
return getRGBComponents(components);
}
int nColorComps = this.fvalue.length;
if (components == null) {
components = new float[(nColorComps + 1)];
}
getColorComponents(components);
components[nColorComps] = this.falpha;
return components;
}
public float[] getColorComponents(float[] components) {
if (this.fvalue == null) {
return getRGBColorComponents(components);
}
if (components == null) {
components = new float[this.fvalue.length];
}
for (int i = 0; i < this.fvalue.length; i++) {
components[i] = this.fvalue[i];
}
return components;
}
public int hashCode() {
return this.value;
}
public int getRed() {
return (this.value >> 16) & 255;
}
public int getRGB() {
return this.value;
}
public int getGreen() {
return (this.value >> 8) & 255;
}
public int getBlue() {
return this.value & 255;
}
public int getAlpha() {
return (this.value >> 24) & 255;
}
public static Color getColor(String nm, Color def) {
Integer integer = Integer.getInteger(nm);
return integer == null ? def : new Color(integer.intValue());
}
public static Color getColor(String nm, int def) {
Integer integer = Integer.getInteger(nm);
if (integer == null) {
return new Color(def);
}
return new Color(integer.intValue());
}
public static Color getColor(String nm) {
Integer integer = Integer.getInteger(nm);
if (integer == null) {
return null;
}
return new Color(integer.intValue());
}
public static Color decode(String nm) throws NumberFormatException {
return new Color(Integer.decode(nm).intValue());
}
public static Color getHSBColor(float h, float s, float b) {
return new Color(HSBtoRGB(h, s, b));
}
public static float[] RGBtoHSB(int r, int g, int b, float[] hsbvals) {
float S;
float H;
if (hsbvals == null) {
hsbvals = new float[MIN_SCALABLE];
}
int V = Math.max(b, Math.max(r, g));
int temp = Math.min(b, Math.min(r, g));
float B = ((float) V) / 255.0f;
if (V == temp) {
S = 0.0f;
H = 0.0f;
} else {
S = ((float) (V - temp)) / ((float) V);
float Cr = ((float) (V - r)) / ((float) (V - temp));
float Cg = ((float) (V - g)) / ((float) (V - temp));
float Cb = ((float) (V - b)) / ((float) (V - temp));
if (r == V) {
H = Cb - Cg;
} else if (g == V) {
H = (2.0f + Cr) - Cb;
} else {
H = (4.0f + Cg) - Cr;
}
H /= 6.0f;
if (H < 0.0f) {
H += 1.0f;
}
}
hsbvals[0] = H;
hsbvals[1] = S;
hsbvals[2] = B;
return hsbvals;
}
public static int HSBtoRGB(float hue, float saturation, float brightness) {
float fr;
float fg;
float fb;
if (saturation != 0.0f) {
float H = (hue - ((float) Math.floor((double) hue))) * 6.0f;
int I = (int) Math.floor((double) H);
float F = H - ((float) I);
float M = brightness * (1.0f - saturation);
float N = brightness * (1.0f - (saturation * F));
float K = brightness * (1.0f - ((1.0f - F) * saturation));
switch (I) {
case 0:
fr = brightness;
fg = K;
fb = M;
break;
case 1:
fr = N;
fg = brightness;
fb = M;
break;
case 2:
fr = M;
fg = brightness;
fb = K;
break;
case MIN_SCALABLE /*3*/:
fr = M;
fg = N;
fb = brightness;
break;
case 4:
fr = K;
fg = M;
fb = brightness;
break;
case 5:
fr = brightness;
fg = M;
fb = N;
break;
default:
fg = 0.0f;
fb = 0.0f;
fr = 0.0f;
break;
}
}
fb = brightness;
fg = brightness;
fr = brightness;
return (((((int) ((((double) fr) * 255.0d) + 0.5d)) << 16) | (((int) ((((double) fg) * 255.0d) + 0.5d)) << 8)) | ((int) ((((double) fb) * 255.0d) + 0.5d))) | -16777216;
}
}
+607
View File
@@ -0,0 +1,607 @@
package java.awt;
import java.beans.*;
import org.apache.harmony.awt.wtk.*;
public class Component {
int x;
int y;
int w = 0;
int h = 0;
protected boolean enabled = true;
private boolean inputMethodsEnabled = true;
transient boolean dispatchToIM = true;
private boolean focusable = true; // By default, all Components return
boolean visible = true;
private boolean wasShowing;
private boolean wasDisplayable;
private boolean valid;
private Dimension defaultMinimumSize;
private ComponentOrientation orientation;
private PropertyChangeSupport propertyChangeSupport;
private Dimension maximumSize;
private Dimension minimumSize;
private Dimension preferredSize;
private Color backColor = Color.WHITE;
private Color foreColor = Color.BLACK;
public Container parent = null;
private int boundsMaskParam = 0;
private Cursor cursor;
private Font font;
private boolean calledSetFocusable;
public Cursor getCursor() {
if (cursor != null) {
return cursor;
// ???AWT
} else if (parent != null) {
return parent.getCursor();
}
return Cursor.getDefaultCursor();
}
public void setCursor(Cursor cursor) {
this.cursor = cursor;
setCursor();
}
void setCursor() {
if (isDisplayable()) { // && isShowing()) {
// Rectangle absRect = new Rectangle(getLocationOnScreen(), getSize());
//Point absPointerPos = toolkit.dispatcher.mouseDispatcher.getPointerPos();
// ???AWT
/*
* if (absRect.contains(absPointerPos)) { // set Cursor only on
* top-level Windows(on X11) Window topLevelWnd =
* getWindowAncestor(); if (topLevelWnd != null) { Point pointerPos
* = MouseDispatcher.convertPoint(null, absPointerPos, topLevelWnd);
* Component compUnderCursor =
* topLevelWnd.findComponentAt(pointerPos); // if (compUnderCursor
* == this || // compUnderCursor.getCursorAncestor() == this) {
* NativeWindow wnd = topLevelWnd.getNativeWindow(); if
* (compUnderCursor != null && wnd != null) {
* compUnderCursor.getRealCursor().getNativeCursor()
* .setCursor(wnd.getId()); } // } } }
*/
}
}
public void setFocusable(boolean focusable) { boolean oldFocusable;
calledSetFocusable = true;
oldFocusable = this.focusable;
this.focusable = focusable;
if (!focusable) {
moveFocus();
}
firePropertyChange("focusable", oldFocusable, focusable); //$NON-NLS-1$
}
void moveFocus() {
// Fake method
}
public void setFont(Font f) {
Font oldFont;
oldFont = font;
setFontImpl(f);
firePropertyChange("font", oldFont, font); //$NON-NLS-1$
}
void setFontImpl(Font f) {
font = f;
invalidate();
/*
if (isShowing()) {
repaint();
}
*/
}
public int getBaseline(int width, int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException(
"Width and height must be >= 0");
}
return -1;
}
public void setLocation(Point p) {
setLocation(p.x, p.y);
}
public void setLocation(int x, int y) {
move(x, y);
}
public void move(int x, int y) {
boundsMaskParam = NativeWindow.BOUNDS_NOSIZE;
setBounds(x, y, w, h);
}
public void repaint() {
// Android implementation, don't need to paint.
}
public void validate() {
validateImpl();
}
void validateImpl() {
valid = true;
}
public void addNotify() {
/*
toolkit.lockAWT();
try {
prepare4HierarchyChange();
//behaviour.addNotify();
// ???AWT
// finishHierarchyChange(this, parent, 0);
// if (dropTarget != null) {
// dropTarget.addNotify(peer);
// }
} finally {
toolkit.unlockAWT();
}
*/
}
Insets getNativeInsets() {
return new Insets(0, 0, 0, 0);
}
Insets getInsets() {
return new Insets(0, 0, 0, 0);
}
Color getDefaultBackground() {
// ???AWT: return getWindowAncestor().getDefaultBackground();
return getBackground();
}
Color getDefaultForeground() {
// ???AWT return getWindowAncestor().getDefaultForeground();
return getForeground();
}
public Color getBackground() {
if (backColor == null && parent != null) {
return parent.getBackground();
}
return backColor;
}
public Color getForeground() {
if (foreColor == null && parent != null) {
return parent.getForeground();
}
return foreColor;
}
public boolean isBackgroundSet() {
return backColor != null;
}
public Color getTextColor() {
Color c = getForeground();
return (c != null) ? c : getDefaultForeground();
}
public void setForeground(Color c) {
Color oldFgColor;
oldFgColor = foreColor;
foreColor = c;
firePropertyChange("foreground", oldFgColor, foreColor); //$NON-NLS-1$
repaint();
}
public void setBackground(Color c) {
Color oldBkColor;
oldBkColor = backColor;
backColor = c;
firePropertyChange("background", oldBkColor, backColor); //$NON-NLS-1$
repaint();
}
public boolean isMaximumSizeSet() {
return maximumSize != null;
}
public boolean isMinimumSizeSet() {
return minimumSize != null;
}
public boolean isPreferredSizeSet() {
return preferredSize != null;
}
public Dimension getMaximumSize() {
return isMaximumSizeSet() ? new Dimension(maximumSize) : new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
}
public Dimension getMinimumSize() {
return minimumSize();
}
@Deprecated
public Dimension minimumSize() {
if (isMinimumSizeSet()) {
return (Dimension)minimumSize.clone();
}
Dimension defSize = getDefaultMinimumSize();
if (defSize != null) {
return (Dimension)defSize.clone();
}
return isDisplayable() ? new Dimension(1, 1) : new Dimension(w, h);
}
public Dimension getPreferredSize() {
return preferredSize();
}
@Deprecated
public Dimension preferredSize() {
if (isPreferredSizeSet()) {
return new Dimension(preferredSize);
}
Dimension defSize = getDefaultPreferredSize();
if (defSize != null) {
return new Dimension(defSize);
}
return new Dimension(getMinimumSize());
}
public void setMaximumSize(Dimension maximumSize) {
Dimension oldMaximumSize;
oldMaximumSize = this.maximumSize;
if (oldMaximumSize != null) {
oldMaximumSize = oldMaximumSize.getSize();
}
if (this.maximumSize == null) {
if (maximumSize != null) {
this.maximumSize = new Dimension(maximumSize);
}
} else {
if (maximumSize != null) {
this.maximumSize.setSize(maximumSize);
} else {
this.maximumSize = null;
}
}
firePropertyChange("maximumSize", oldMaximumSize, this.maximumSize); //$NON-NLS-1$
}
public void setMinimumSize(Dimension minimumSize) {
Dimension oldMinimumSize;
oldMinimumSize = this.minimumSize;
if (oldMinimumSize != null) {
oldMinimumSize = oldMinimumSize.getSize();
}
if (this.minimumSize == null) {
if (minimumSize != null) {
this.minimumSize = new Dimension(minimumSize);
}
} else {
if (minimumSize != null) {
this.minimumSize.setSize(minimumSize);
} else {
this.minimumSize = null;
}
}
firePropertyChange("minimumSize", oldMinimumSize, this.minimumSize); //$NON-NLS-1$
}
public void setPreferredSize(Dimension preferredSize) {
Dimension oldPreferredSize;
oldPreferredSize = this.preferredSize;
if (oldPreferredSize != null) {
oldPreferredSize = oldPreferredSize.getSize();
}
if (this.preferredSize == null) {
if (preferredSize != null) {
this.preferredSize = new Dimension(preferredSize);
}
} else {
if (preferredSize != null) {
this.preferredSize.setSize(preferredSize);
} else {
this.preferredSize = null;
}
}
firePropertyChange("preferredSize", oldPreferredSize, this.preferredSize); //$NON-NLS-1$
}
Dimension getDefaultMinimumSize() {
return null;
}
Dimension getDefaultPreferredSize() {
return null;
}
void resetDefaultSize() {
}
public boolean isEnabled() {
return enabled;
}
public boolean isVisible() {
return visible;
}
public boolean isDisplayable() {
return isVisible(); //behaviour.isDisplayable();
}
public void setVisible(boolean b) {
// show() & hide() are not deprecated for Window,
// so have to call them from setVisible()
show(b);
}
/**
* Deprecated: replaced by setVisible(boolean) method.
*
* @deprecated Replaced by setVisible(boolean) method.
*/
@Deprecated
public void show() {
if (visible) {
return;
}
/*
prepare4HierarchyChange();
mapToDisplay(true);
validate();
*/
visible = true;
/*
//behaviour.setVisible(true);
postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_SHOWN));
// ???AWT: finishHierarchyChange(this, parent, 0);
notifyInputMethod(new Rectangle(x, y, w, h));
// ???AWT: invalidateRealParent();
*/
}
public void hide() {
if (!visible) {
return;
}
// prepare4HierarchyChange();
visible = false;
/*
moveFocusOnHide();
//behaviour.setVisible(false);
postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_HIDDEN));
// ???AWT: finishHierarchyChange(this, parent, 0);
notifyInputMethod(null);
// ???AWT: invalidateRealParent();
*/
}
@Deprecated
public void show(boolean b) {
if (b) {
show();
} else {
hide();
}
}
public void applyComponentOrientation(ComponentOrientation orientation) {
if (orientation == null) {
throw new NullPointerException();
}
setComponentOrientation(orientation);
}
public ComponentOrientation getComponentOrientation() {
return orientation;
}
public void setComponentOrientation(ComponentOrientation o) {
ComponentOrientation oldOrientation;
oldOrientation = orientation;
orientation = o;
firePropertyChange("componentOrientation", oldOrientation, orientation); //$NON-NLS-1$
invalidate();
}
/*
final boolean canBeFocusOwner() {
// It is enabled, visible, focusable.
if (isEnabled() && isDisplayable() && isVisible() && isFocusable()) {
return true;
}
return false;
}
*/
public boolean inside(int x, int y) {
return x >= 0 && x < getWidth() && y >= 0 && y < getHeight();
}
public boolean isValid() {
return valid; //&& behaviour.isDisplayable();
}
public void invalidate() {
valid = false;
resetDefaultSize();
}
void invalidateParent() {
if (parent != null) {
parent.invalidateIfValid();
}
}
final void invalidateIfValid() {
if (isValid()) {
invalidate();
}
}
public void addPropertyChangeListener(//String name,
PropertyChangeListener listener) {
if (listener == null) {
return;
}
if (propertyChangeSupport == null) {
propertyChangeSupport = new PropertyChangeSupport(this);
}
propertyChangeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(
PropertyChangeListener listener) {
if (listener == null || propertyChangeSupport == null) {
return;
}
propertyChangeSupport.removePropertyChangeListener(listener);
}
private void firePropertyChangeImpl(String propertyName, Object oldValue, Object newValue) {
PropertyChangeSupport pcs;
if (propertyChangeSupport == null) {
return;
}
pcs = propertyChangeSupport;
pcs.firePropertyChange(propertyName, oldValue, newValue);
}
protected void firePropertyChange(String propertyName, int oldValue, int newValue) {
firePropertyChangeImpl(propertyName, new Integer(oldValue), new Integer(newValue));
}
protected void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
firePropertyChangeImpl(propertyName, Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
}
protected void firePropertyChange(final String propertyName, final Object oldValue,
final Object newValue) {
firePropertyChangeImpl(propertyName, oldValue, newValue);
}
public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
firePropertyChangeImpl(propertyName, new Byte(oldValue), new Byte(newValue));
}
public void firePropertyChange(String propertyName, char oldValue, char newValue) {
firePropertyChangeImpl(propertyName, new Character(oldValue), new Character(newValue));
}
public void firePropertyChange(String propertyName, short oldValue, short newValue) {
firePropertyChangeImpl(propertyName, new Short(oldValue), new Short(newValue));
}
public void firePropertyChange(String propertyName, long oldValue, long newValue) {
firePropertyChangeImpl(propertyName, new Long(oldValue), new Long(newValue));
}
public void firePropertyChange(String propertyName, float oldValue, float newValue) {
firePropertyChangeImpl(propertyName, new Float(oldValue), new Float(newValue));
}
public void firePropertyChange(String propertyName, double oldValue, double newValue) {
firePropertyChangeImpl(propertyName, new Double(oldValue), new Double(newValue));
}
public void setSize(int width, int height) {
// toolkit.lockAWT();
try {
resize(width, height);
} finally {
// toolkit.unlockAWT();
}
}
/**
* Sets the size of the Component specified by Dimension object.
*
* @param d
* the new size of the Component.
*/
public void setSize(Dimension d) {
resize(d);
}
public void resize(int width, int height) {
boundsMaskParam = NativeWindow.BOUNDS_NOMOVE;
setBounds(x, y, width, height);
// MOD: impl
// graphics.resize(width, height);
}
public void reshape(int x, int y, int w, int h) {
setBounds(x, y, w, h, boundsMaskParam, true);
boundsMaskParam = 0;
}
public void setBounds(int x, int y, int w, int h) {
reshape(x, y, w, h);
}
void setBounds(int x, int y, int w, int h, int bMask, boolean updateBehavior) {
int oldX = this.x;
int oldY = this.y;
int oldW = this.w;
int oldH = this.h;
setBoundsFields(x, y, w, h, bMask);
// Moved
/*
if ((oldX != this.x) || (oldY != this.y)) {
// ???AWT: invalidateRealParent();
postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_MOVED));
spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_MOVED);
}
// Resized
if ((oldW != this.w) || (oldH != this.h)) {
invalidate();
postEvent(new ComponentEvent(this, ComponentEvent.COMPONENT_RESIZED));
spreadHierarchyBoundsEvents(this, HierarchyEvent.ANCESTOR_RESIZED);
}
if (updateBehavior) {
//behaviour.setBounds(this.x, this.y, this.w, this.h, bMask);
}
notifyInputMethod(new Rectangle(x, y, w, h));
*/
}
private void setBoundsFields(int x, int y, int w, int h, int bMask) {
if ((bMask & NativeWindow.BOUNDS_NOSIZE) == 0) {
this.w = w;
this.h = h;
}
if ((bMask & NativeWindow.BOUNDS_NOMOVE) == 0) {
this.x = x;
this.y = y;
}
}
public void resize(Dimension size) {
setSize(size.width, size.height);
}
public int getWidth() {
return w;
}
public int getHeight() {
return h;
}
}
@@ -0,0 +1,154 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Michael Danilov, Dmitry A. Durnev
* @version $Revision$
*/
package java.awt;
import java.io.Serializable;
import java.util.*;
/**
* The ComponentOrientation class specifies the language-sensitive orientation
* of component's elements or text. It is used to reflect the differences in
* this ordering between different writing systems. The ComponentOrientation
* class indicates the orientation of the elements/text in the horizontal
* direction ("left to right" or "right to left") and in the vertical direction
* ("top to bottom" or "bottom to top").
*
* @since Android 1.0
*/
public final class ComponentOrientation implements Serializable {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = -4113291392143563828L;
/**
* The Constant LEFT_TO_RIGHT indicates that items run left to right.
*/
public static final ComponentOrientation LEFT_TO_RIGHT = new ComponentOrientation(true, true);
/**
* The Constant RIGHT_TO_LEFT indicates that items run right to left.
*/
public static final ComponentOrientation RIGHT_TO_LEFT = new ComponentOrientation(true, false);
/**
* The Constant UNKNOWN indicates that a component's orientation is not set.
*/
public static final ComponentOrientation UNKNOWN = new ComponentOrientation(true, true);
/**
* The Constant rlLangs.
*/
private static final Set<String> rlLangs = new HashSet<String>(); // RIGHT_TO_LEFT
// languages
/**
* The horizontal.
*/
private final boolean horizontal;
/**
* The left2right.
*/
private final boolean left2right;
static {
rlLangs.add("ar"); //$NON-NLS-1$
rlLangs.add("fa"); //$NON-NLS-1$
rlLangs.add("iw"); //$NON-NLS-1$
rlLangs.add("ur"); //$NON-NLS-1$
}
/**
* Gets the orientation for the given ResourceBundle's localization.
*
* @param bdl
* the ResourceBundle.
* @return the ComponentOrientation.
* @deprecated Use getOrientation(java.util.Locale) method.
*/
@Deprecated
public static ComponentOrientation getOrientation(ResourceBundle bdl) {
Object obj = null;
try {
obj = bdl.getObject("Orientation"); //$NON-NLS-1$
} catch (MissingResourceException mre) {
obj = null;
}
if (obj instanceof ComponentOrientation) {
return (ComponentOrientation)obj;
}
Locale locale = bdl.getLocale();
if (locale == null) {
locale = Locale.getDefault();
}
return getOrientation(locale);
}
/**
* Gets the orientation for the specified locale.
*
* @param locale
* the specified Locale.
* @return the ComponentOrientation.
*/
public static ComponentOrientation getOrientation(Locale locale) {
String lang = locale.getLanguage();
return rlLangs.contains(lang) ? RIGHT_TO_LEFT : LEFT_TO_RIGHT;
}
/**
* Instantiates a new component orientation.
*
* @param hor
* whether the items should be arranged horizontally.
* @param l2r
* whether this orientation specifies a left-to-right flow.
*/
private ComponentOrientation(boolean hor, boolean l2r) {
horizontal = hor;
left2right = l2r;
}
/**
* Returns true if the text of the of writing systems arranged horizontally.
*
* @return true, if the text is written horizontally, false for a vertical
* arrangement.
*/
public boolean isHorizontal() {
return horizontal;
}
/**
* Returns true if the text is arranged from left to right.
*
* @return true, for writing systems written from left to right; false for
* right-to-left.
*/
public boolean isLeftToRight() {
return left2right;
}
}
@@ -0,0 +1,37 @@
/*
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package java.awt;
/**
* Conditional is used by the EventDispatchThread's message pumps to
* determine if a given pump should continue to run, or should instead exit
* and yield control to the parent pump.
*
* @author David Mendenhall
*/
interface Conditional {
boolean evaluate();
}
+233
View File
@@ -0,0 +1,233 @@
package java.awt;
public class Container extends Component
{
private java.util.List<Component> component = new java.util.ArrayList<Component>();
LayoutManager layoutMgr;
public void setLayout(LayoutManager mgr) {
layoutMgr = mgr;
}
public void doLayout() {
// layout();
}
public Component getComponent(int n) {
// This method is not synchronized under AWT tree lock.
// Instead, the calling code is responsible for the
// synchronization. See 6784816 for details.
try {
return component.get(n);
} catch (IndexOutOfBoundsException z) {
throw new ArrayIndexOutOfBoundsException("No such child: " + n);
}
}
public int getComponentCount() {
return countComponents();
}
@Deprecated
public int countComponents() {
// This method is not synchronized under AWT tree lock.
// Instead, the calling code is responsible for the
// synchronization. See 6784816 for details.
return component.size();
}
public void add(Component comp, Object constraints) {
addImpl(comp, constraints, -1);
}
private void checkAddToSelf(Component comp){
if (comp instanceof Container) {
for (Container cn = this; cn != null; cn=cn.parent) {
if (cn == comp) {
throw new IllegalArgumentException("adding container's parent to itself");
}
}
}
}
private void checkNotAWindow(Component comp){
if (comp instanceof Window) {
throw new IllegalArgumentException("adding a window to a container");
}
}
public void add(Component comp, Object constraints, int index) {
addImpl(comp, constraints, index);
}
protected void addImpl(Component comp, Object constraints, int index) {
/* Check for correct arguments: index in bounds,
* comp cannot be one of this container's parents,
* and comp cannot be a window.
* comp and container must be on the same GraphicsDevice.
* if comp is container, all sub-components must be on
* same GraphicsDevice.
*/
// GraphicsConfiguration thisGC = this.getGraphicsConfiguration();
if (index > component.size() || (index < 0 && index != -1)) {
throw new IllegalArgumentException(
"illegal component position");
}
checkAddToSelf(comp);
checkNotAWindow(comp);
/*
if (thisGC != null) {
comp.checkGD(thisGC.getDevice().getIDstring());
}
*/
/* Reparent the component and tidy up the tree's state. */
if (comp.parent != null) {
comp.parent.remove(comp);
if (index > component.size()) {
throw new IllegalArgumentException("illegal component position");
}
}
//index == -1 means add to the end.
if (index == -1) {
component.add(comp);
} else {
component.add(index, comp);
}
comp.parent = this;
/*
comp.setGraphicsConfiguration(thisGC);
adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
adjustDescendants(comp.countHierarchyMembers());
invalidateIfValid();
if (peer != null) {
comp.addNotify();
}
*/
/* Notify the layout manager of the added component. */
if (layoutMgr != null) {
if (layoutMgr instanceof LayoutManager2) {
((LayoutManager2)layoutMgr).addLayoutComponent(comp, constraints);
} else if (constraints instanceof String) {
layoutMgr.addLayoutComponent((String)constraints, comp);
}
}
/*
if (containerListener != null ||
(eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
ContainerEvent e = new ContainerEvent(this,
ContainerEvent.COMPONENT_ADDED,
comp);
dispatchEvent(e);
}
comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
this, HierarchyEvent.PARENT_CHANGED,
Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
if (peer != null && layoutMgr == null && isVisible()) {
updateCursorImmediately();
}
*/
}
public void removeAll() {
/*
adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
-listeningChildren);
adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
-listeningBoundsChildren);
adjustDescendants(-descendantsCount);
*/
while (!component.isEmpty()) {
Component comp = component.remove(component.size()-1);
/*
if (peer != null) {
comp.removeNotify();
}
*/
if (layoutMgr != null) {
layoutMgr.removeLayoutComponent(comp);
}
comp.parent = null;
/*
comp.setGraphicsConfiguration(null);
if (containerListener != null ||
(eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
ContainerEvent e = new ContainerEvent(this,
ContainerEvent.COMPONENT_REMOVED,
comp);
dispatchEvent(e);
}
comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED,
comp, this,
HierarchyEvent.PARENT_CHANGED,
Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
*/
}
/*
if (peer != null && layoutMgr == null && isVisible()) {
updateCursorImmediately();
}
*/
invalidateIfValid();
}
public void remove(Component comp) {
if (comp.parent == this) {
int index = component.indexOf(comp);
if (index >= 0) {
remove(index);
}
}
}
public void remove(int index) {
if (index < 0 || index >= component.size()) {
throw new ArrayIndexOutOfBoundsException(index);
}
Component comp = component.get(index);
/*
if (peer != null) {
comp.removeNotify();
}
*/
if (layoutMgr != null) {
layoutMgr.removeLayoutComponent(comp);
}
/*
adjustListeningChildren(AWTEvent.HIERARCHY_EVENT_MASK,
-comp.numListening(AWTEvent.HIERARCHY_EVENT_MASK));
adjustListeningChildren(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK,
-comp.numListening(AWTEvent.HIERARCHY_BOUNDS_EVENT_MASK));
adjustDescendants(-(comp.countHierarchyMembers()));
*/
comp.parent = null;
component.remove(index);
/*
comp.setGraphicsConfiguration(null);
invalidateIfValid();
if (containerListener != null ||
(eventMask & AWTEvent.CONTAINER_EVENT_MASK) != 0 ||
Toolkit.enabledOnToolkit(AWTEvent.CONTAINER_EVENT_MASK)) {
ContainerEvent e = new ContainerEvent(this,
ContainerEvent.COMPONENT_REMOVED,
comp);
dispatchEvent(e);
}
comp.createHierarchyEvents(HierarchyEvent.HIERARCHY_CHANGED, comp,
this, HierarchyEvent.PARENT_CHANGED,
Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK));
if (peer != null && layoutMgr == null && isVisible()) {
updateCursorImmediately();
}
*/
}
}
+427
View File
@@ -0,0 +1,427 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Dmitry A. Durnev
* @version $Revision$
*/
package java.awt;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.harmony.awt.internal.nls.Messages;
import org.apache.harmony.awt.wtk.NativeCursor;
/**
* The Cursor class represents the bitmap of the mouse cursor.
*
* @since Android 1.0
*/
public class Cursor implements Serializable {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = 8028237497568985504L;
/**
* The Constant DEFAULT_CURSOR indicates the default cursor type.
*/
public static final int DEFAULT_CURSOR = 0;
/**
* The Constant CROSSHAIR_CURSOR cursor type.
*/
public static final int CROSSHAIR_CURSOR = 1;
/**
* The Constant TEXT_CURSOR cursor type.
*/
public static final int TEXT_CURSOR = 2;
/**
* The Constant WAIT_CURSOR cursor type.
*/
public static final int WAIT_CURSOR = 3;
/**
* The Constant SW_RESIZE_CURSOR cursor type.
*/
public static final int SW_RESIZE_CURSOR = 4;
/**
* The Constant SE_RESIZE_CURSOR cursor type.
*/
public static final int SE_RESIZE_CURSOR = 5;
/**
* The Constant NW_RESIZE_CURSOR cursor type.
*/
public static final int NW_RESIZE_CURSOR = 6;
/**
* The Constant NE_RESIZE_CURSOR cursor type.
*/
public static final int NE_RESIZE_CURSOR = 7;
/**
* The Constant N_RESIZE_CURSOR cursor type.
*/
public static final int N_RESIZE_CURSOR = 8;
/**
* The Constant S_RESIZE_CURSOR cursor type.
*/
public static final int S_RESIZE_CURSOR = 9;
/**
* The Constant W_RESIZE_CURSOR cursor type.
*/
public static final int W_RESIZE_CURSOR = 10;
/**
* The Constant E_RESIZE_CURSOR cursor type.
*/
public static final int E_RESIZE_CURSOR = 11;
/**
* The Constant HAND_CURSOR cursor type.
*/
public static final int HAND_CURSOR = 12;
/**
* The Constant MOVE_CURSOR cursor type.
*/
public static final int MOVE_CURSOR = 13;
/**
* A mapping from names to system custom cursors.
*/
static Map<String, Cursor> systemCustomCursors;
/**
* The cursor props.
*/
static Properties cursorProps;
/**
* The Constant predefinedNames.
*/
static final String[] predefinedNames = {
"Default", "Crosshair", "Text", "Wait", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"Southwest Resize", "Southeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
"Northwest Resize", "Northeast Resize", //$NON-NLS-1$ //$NON-NLS-2$
"North Resize", "South Resize", "West Resize", "East Resize", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
"Hand", "Move" //$NON-NLS-1$ //$NON-NLS-2$
};
/**
* The predefined set of cursors.
*/
protected static Cursor[] predefined = {
new Cursor(DEFAULT_CURSOR), null, null, null, null, null, null, null, null, null, null,
null, null, null
};
/**
* The Constant CUSTOM_CURSOR is associated with all custom cursor types.
* (Those which are not predefined)
*/
public static final int CUSTOM_CURSOR = -1;
/**
* The name of the cursor.
*/
protected String name;
/**
* The type of the cursor, chosen from the list of cursor type constants.
*/
private final int type;
/**
* The native cursor.
*/
private transient NativeCursor nativeCursor;
/**
* The exact point on the cursor image that indicates which point the cursor
* is selecting (pointing to). The coordinates are given with respect the
* origin of the Image (its upper left corner).
*/
private Point hotSpot;
/**
* The image to draw on the screen representing the cursor.
*/
private Image image;
/**
* Instantiates a new cursor with the specified name.
*
* @param name
* the name of cursor.
*/
protected Cursor(String name) {
this(name, null, new Point());
}
/**
* Instantiates a new cursor of the specified type.
*
* @param type
* the type of cursor.
*/
public Cursor(int type) {
checkType(type);
this.type = type;
if ((type >= 0) && (type < predefinedNames.length)) {
name = predefinedNames[type] + " Cursor"; //$NON-NLS-1$
}
}
/**
* Instantiates a new cursor.
*
* @param name
* the name.
* @param img
* the img.
* @param hotSpot
* the hot spot.
*/
Cursor(String name, Image img, Point hotSpot) {
this.name = name;
type = CUSTOM_CURSOR;
this.hotSpot = hotSpot;
image = img;
}
/**
* Finalize method overrides the finalize method from Object class.
*
* @throws Throwable
* if the native cursor is not null and throws a Throwable when
* destroyed.
*/
@Override
protected void finalize() throws Throwable {
if (nativeCursor != null) {
nativeCursor.destroyCursor();
}
}
/**
* Gets the name of the cursor.
*
* @return the name of the cursor.
*/
public String getName() {
return name;
}
/**
* Returns the String representation of the cursor.
*
* @return the String representation of the cursor.
*/
@Override
public String toString() {
return getClass().getName() + "[" + name + "]"; //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Gets the cursor type.
*
* @return the cursor type.
*/
public int getType() {
return type;
}
/**
* Gets the predefined cursor with the specified type.
*
* @param type
* the type of cursor.
* @return the predefined cursor with the specified type.
*/
public static Cursor getPredefinedCursor(int type) {
checkType(type);
Cursor cursor = predefined[type];
if (cursor == null) {
cursor = new Cursor(type);
predefined[type] = cursor;
}
return cursor;
}
/**
* Gets the default cursor.
*
* @return the default cursor.
*/
public static Cursor getDefaultCursor() {
return getPredefinedCursor(DEFAULT_CURSOR);
}
/**
* Gets the specified system custom cursor.
*
* @param name
* the name of the desired system cursor.
* @return the specific system cursor with the specified name.
* @throws AWTException
* if the desired cursor has malformed data such as an
* incorrectly defined hot spot.
* @throws HeadlessException
* if the isHeadless method of the GraphicsEnvironment returns
* true.
*/
public static Cursor getSystemCustomCursor(String name) throws AWTException, HeadlessException {
Toolkit.checkHeadless();
return getSystemCustomCursorFromMap(name);
}
/**
* Gets the specified system custom cursor from the map of system custom
* cursors.
*
* @param name
* the name of the desired cursor.
* @return the desired system custom cursor from the map of system custom
* cursors.
* @throws AWTException
* the AWT exception.
*/
private static Cursor getSystemCustomCursorFromMap(String name) throws AWTException {
loadCursorProps();
if (systemCustomCursors == null) {
systemCustomCursors = new HashMap<String, Cursor>();
}
Cursor cursor = systemCustomCursors.get(name);
if (cursor != null) {
return cursor;
}
// awt.141=failed to parse hotspot property for cursor:
String exMsg = Messages.getString("awt.141") + name; //$NON-NLS-1$
String nm = "Cursor." + name; //$NON-NLS-1$
String nameStr = cursorProps.getProperty(nm + ".Name"); //$NON-NLS-1$
String hotSpotStr = cursorProps.getProperty(nm + ".HotSpot"); //$NON-NLS-1$
String fileStr = cursorProps.getProperty(nm + ".File"); //$NON-NLS-1$
int idx = hotSpotStr.indexOf(',');
if (idx < 0) {
throw new AWTException(exMsg);
}
int x, y;
try {
x = new Integer(hotSpotStr.substring(0, idx)).intValue();
y = new Integer(hotSpotStr.substring(idx + 1, hotSpotStr.length())).intValue();
} catch (NumberFormatException nfe) {
throw new AWTException(exMsg);
}
Image img = Toolkit.getDefaultToolkit().createImage(fileStr);
cursor = new Cursor(nameStr, img, new Point(x, y));
systemCustomCursors.put(name, cursor);
return cursor;
}
/**
* Load cursor props.
*
* @throws AWTException
* the AWT exception.
*/
private static void loadCursorProps() throws AWTException {
if (cursorProps != null) {
return;
}
String sep = File.separator;
String cursorsDir = "lib" + sep + "images" + sep + "cursors"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
String cursorsAbsDir = System.getProperty("java.home") + sep + //$NON-NLS-1$
cursorsDir;
String cursorPropsFileName = "cursors.properties"; //$NON-NLS-1$
String cursorPropsFullFileName = (cursorsAbsDir + sep + cursorPropsFileName);
cursorProps = new Properties();
try {
cursorProps.load(new FileInputStream(new File(cursorPropsFullFileName)));
} catch (FileNotFoundException e) {
// awt.142=Exception: class {0} {1} occurred while loading: {2}
throw new AWTException(Messages.getString("awt.142",//$NON-NLS-1$
new Object[] {
e.getClass(), e.getMessage(), cursorPropsFullFileName
}));
} catch (IOException e) {
throw new AWTException(e.getMessage());
}
}
/**
* Check type.
*
* @param type
* the type.
*/
static void checkType(int type) {
// can't use predefined array here because it may not have been
// initialized yet
if ((type < 0) || (type >= predefinedNames.length)) {
// awt.143=illegal cursor type
throw new IllegalArgumentException(Messages.getString("awt.143")); //$NON-NLS-1$
}
}
// "lazily" create native cursors:
/**
* Gets the native cursor.
*
* @return the native cursor.
*/
NativeCursor getNativeCursor() {
if (nativeCursor != null) {
return nativeCursor;
}/*
Toolkit toolkit = Toolkit.getDefaultToolkit();
if (type != CUSTOM_CURSOR) {
nativeCursor = toolkit.createNativeCursor(type);
} else {
nativeCursor = toolkit.createCustomNativeCursor(image, hotSpot, name);
}*/
return nativeCursor;
}
/**
* Sets the native cursor.
*
* @param nativeCursor
* the new native cursor.
*/
void setNativeCursor(NativeCursor nativeCursor) {
this.nativeCursor = nativeCursor;
}
}
+71
View File
@@ -0,0 +1,71 @@
package java.awt;
import android.content.*;
import android.net.*;
import android.util.*;
import java.awt.peer.*;
import java.io.*;
import java.net.*;
import net.kdt.pojavlaunch.MainActivity;
import android.app.*;
import net.kdt.pojavlaunch.*;
import java.awt.mod.*;
public class Desktop
{
private MainActivity currentActivity;
public enum Action
{
BROWSE, EDIT, MAIL, OPEN, PRINT
}
private DesktopPeer peer;
public Desktop()
{
peer = Toolkit.getDefaultToolkit().createDesktopPeer();
try
{
if (currentActivity == null) currentActivity = ModdingKit.getCurrentActivity();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
public static Desktop getDesktop()
{
return new Desktop();
}
public static boolean isDesktopSupported()
{
return true;
}
public boolean isSupported(Action action)
{
return true;
}
public void browse(URI uri)
{
try {
URL url = uri.toURL();
if(url.toString().startsWith("file:")){
String fPath = url.toString().replace("file:", "");
Log.d("MineDebug:java.awt.Desktop", "Browse folder: " + fPath);
// Current not implemented
}
else{
Log.d("MineDebug:java.awt.Desktop", "Browse URL: " + url.toString());
if (!url.toString().startsWith("http://") && !url.toString().startsWith("https://")){
url = new URL("http://" + url.toString());
}
currentActivity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url.toString())));
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
+201
View File
@@ -0,0 +1,201 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt;
import java.awt.geom.Dimension2D;
import java.io.Serializable;
import org.apache.harmony.misc.HashCode;
/**
* The Dimension represents the size (width and height) of a component. The
* width and height values can be negative, but in that case the behavior of
* some methods is unexpected.
*
* @since Android 1.0
*/
public class Dimension extends Dimension2D implements Serializable {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = 4723952579491349524L;
/**
* The width dimension.
*/
public int width;
/**
* The height dimension.
*/
public int height;
/**
* Instantiates a new Dimension with the same data as the specified
* Dimension.
*
* @param d
* the Dimension to copy the data from when creating the new
* Dimension object.
*/
public Dimension(Dimension d) {
this(d.width, d.height);
}
/**
* Instantiates a new Dimension with zero width and height.
*/
public Dimension() {
this(0, 0);
}
/**
* Instantiates a new Dimension with the specified width and height.
*
* @param width
* the width of the new Dimension.
* @param height
* the height of the new Dimension.
*/
public Dimension(int width, int height) {
setSize(width, height);
}
/**
* Returns the hash code of the Dimension.
*
* @return the hash code of the Dimension.
*/
@Override
public int hashCode() {
HashCode hash = new HashCode();
hash.append(width);
hash.append(height);
return hash.hashCode();
}
/**
* Compares this Dimension object with the specified object.
*
* @param obj
* the Object to be compared.
* @return true, if the specified Object is a Dimension with the same width
* and height data as this Dimension.
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Dimension) {
Dimension d = (Dimension)obj;
return (d.width == width && d.height == height);
}
return false;
}
/**
* Returns the String associated to this Dimension object.
*
* @return the String associated to this Dimension object.
*/
@Override
public String toString() {
// The output format based on 1.5 release behaviour. It could be
// obtained in the following way
// System.out.println(new Dimension().toString())
return getClass().getName() + "[width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
* Sets the size of this Dimension object with the specified width and
* height.
*
* @param width
* the width of the Dimension.
* @param height
* the height of the Dimension.
*/
public void setSize(int width, int height) {
this.width = width;
this.height = height;
}
/**
* Sets the size of this Dimension object by copying the data from the
* specified Dimension object.
*
* @param d
* the Dimension that gives the new size values.
*/
public void setSize(Dimension d) {
setSize(d.width, d.height);
}
/**
* Sets the size of this Dimension object with the specified double width
* and height.
*
* @param width
* the width of the Dimension.
* @param height
* the height of the Dimension.
* @see java.awt.geom.Dimension2D#setSize(double, double)
*/
@Override
public void setSize(double width, double height) {
setSize((int)Math.ceil(width), (int)Math.ceil(height));
}
/**
* Gets the size of the Dimension.
*
* @return the size of the Dimension.
*/
public Dimension getSize() {
return new Dimension(width, height);
}
/**
* Gets the height of the Dimension.
*
* @return the height of the Dimension.
* @see java.awt.geom.Dimension2D#getHeight()
*/
@Override
public double getHeight() {
return height;
}
/**
* Gets the width of the Dimension.
*
* @return the width of the Dimension.
* @see java.awt.geom.Dimension2D#getWidth()
*/
@Override
public double getWidth() {
return width;
}
}
+165
View File
@@ -0,0 +1,165 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Alexey A. Petrenko
* @version $Revision$
*/
package java.awt;
/**
* The DisplayMode class contains the bit depth, height, width and refresh rate
* of a GraphicsDevice.
*
* @since Android 1.0
*/
public final class DisplayMode {
/**
* The width.
*/
private final int width;
/**
* The height.
*/
private final int height;
/**
* The bit depth.
*/
private final int bitDepth;
/**
* The refresh rate.
*/
private final int refreshRate;
/**
* The Constant Value BIT_DEPTH_MULTI indicates the bit depth
*/
public static final int BIT_DEPTH_MULTI = -1;
/**
* The Constant REFRESH_RATE_UNKNOWN indicates the refresh rate.
*/
public static final int REFRESH_RATE_UNKNOWN = 0;
/**
* Creates a new DisplayMode object with the specified parameters.
*
* @param width
* the width of the display.
* @param height
* the height of the display.
* @param bitDepth
* the bit depth of the display.
* @param refreshRate
* the refresh rate of the display.
*/
public DisplayMode(int width, int height, int bitDepth, int refreshRate) {
this.width = width;
this.height = height;
this.bitDepth = bitDepth;
this.refreshRate = refreshRate;
}
/**
* Compares if this DisplayMode is equal to the specified object or not.
*
* @param dm
* the Object to be compared.
* @return true, if the specified object is a DisplayMode with the same data
* values as this DisplayMode, false otherwise.
*/
@Override
public boolean equals(Object dm) {
if (dm instanceof DisplayMode) {
return equals((DisplayMode)dm);
}
return false;
}
/**
* Compares if this DisplayMode is equal to the specified DisplayMode object
* or not.
*
* @param dm
* the DisplayMode to be compared.
* @return true, if all of the data values of this DisplayMode are equal to
* the values of the specified DisplayMode object, false otherwise.
*/
public boolean equals(DisplayMode dm) {
if (dm == null) {
return false;
}
if (dm.bitDepth != bitDepth) {
return false;
}
if (dm.refreshRate != refreshRate) {
return false;
}
if (dm.width != width) {
return false;
}
if (dm.height != height) {
return false;
}
return true;
}
/**
* Gets the bit depth of the DisplayMode, returns BIT_DEPTH_MULTI value if
* multiple bit depths are supported in this display mode.
*
* @return the bit depth of the DisplayMode.
*/
public int getBitDepth() {
return bitDepth;
}
/**
* Gets the height of the DisplayMode.
*
* @return the height of the DisplayMode.
*/
public int getHeight() {
return height;
}
/**
* Gets the refresh rate of the DisplayMode, returns REFRESH_RATE_UNKNOWN
* value if the information is not available.
*
* @return the refresh rate of the DisplayMode.
*/
public int getRefreshRate() {
return refreshRate;
}
/**
* Gets the width of the DisplayMode.
*
* @return the width of the DisplayMode.
*/
public int getWidth() {
return width;
}
}
+696
View File
@@ -0,0 +1,696 @@
/*
* Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt;
import java.io.ObjectInputStream;
import java.io.IOException;
/**
* A flow layout arranges components in a directional flow, much
* like lines of text in a paragraph. The flow direction is
* determined by the container's <code>componentOrientation</code>
* property and may be one of two values:
* <ul>
* <li><code>ComponentOrientation.LEFT_TO_RIGHT</code>
* <li><code>ComponentOrientation.RIGHT_TO_LEFT</code>
* </ul>
* Flow layouts are typically used
* to arrange buttons in a panel. It arranges buttons
* horizontally until no more buttons fit on the same line.
* The line alignment is determined by the <code>align</code>
* property. The possible values are:
* <ul>
* <li>{@link #LEFT LEFT}
* <li>{@link #RIGHT RIGHT}
* <li>{@link #CENTER CENTER}
* <li>{@link #LEADING LEADING}
* <li>{@link #TRAILING TRAILING}
* </ul>
* <p>
* For example, the following picture shows an applet using the flow
* layout manager (its default layout manager) to position three buttons:
* <p>
* <img src="doc-files/FlowLayout-1.gif"
* ALT="Graphic of Layout for Three Buttons"
* ALIGN=center HSPACE=10 VSPACE=7>
* <p>
* Here is the code for this applet:
* <p>
* <hr><blockquote><pre>
* import java.awt.*;
* import java.applet.Applet;
*
* public class myButtons extends Applet {
* Button button1, button2, button3;
* public void init() {
* button1 = new Button("Ok");
* button2 = new Button("Open");
* button3 = new Button("Close");
* add(button1);
* add(button2);
* add(button3);
* }
* }
* </pre></blockquote><hr>
* <p>
* A flow layout lets each component assume its natural (preferred) size.
*
* @author Arthur van Hoff
* @author Sami Shaio
* @since JDK1.0
* @see ComponentOrientation
*/
public class FlowLayout implements LayoutManager, java.io.Serializable {
/**
* This value indicates that each row of components
* should be left-justified.
*/
public static final int LEFT = 0;
/**
* This value indicates that each row of components
* should be centered.
*/
public static final int CENTER = 1;
/**
* This value indicates that each row of components
* should be right-justified.
*/
public static final int RIGHT = 2;
/**
* This value indicates that each row of components
* should be justified to the leading edge of the container's
* orientation, for example, to the left in left-to-right orientations.
*
* @see java.awt.Component#getComponentOrientation
* @see java.awt.ComponentOrientation
* @since 1.2
*/
public static final int LEADING = 3;
/**
* This value indicates that each row of components
* should be justified to the trailing edge of the container's
* orientation, for example, to the right in left-to-right orientations.
*
* @see java.awt.Component#getComponentOrientation
* @see java.awt.ComponentOrientation
* @since 1.2
*/
public static final int TRAILING = 4;
/**
* <code>align</code> is the property that determines
* how each row distributes empty space.
* It can be one of the following values:
* <ul>
* <code>LEFT</code>
* <code>RIGHT</code>
* <code>CENTER</code>
* </ul>
*
* @serial
* @see #getAlignment
* @see #setAlignment
*/
int align; // This is for 1.1 serialization compatibility
/**
* <code>newAlign</code> is the property that determines
* how each row distributes empty space for the Java 2 platform,
* v1.2 and greater.
* It can be one of the following three values:
* <ul>
* <code>LEFT</code>
* <code>RIGHT</code>
* <code>CENTER</code>
* <code>LEADING</code>
* <code>TRAILING</code>
* </ul>
*
* @serial
* @since 1.2
* @see #getAlignment
* @see #setAlignment
*/
int newAlign; // This is the one we actually use
/**
* The flow layout manager allows a seperation of
* components with gaps. The horizontal gap will
* specify the space between components and between
* the components and the borders of the
* <code>Container</code>.
*
* @serial
* @see #getHgap()
* @see #setHgap(int)
*/
int hgap;
/**
* The flow layout manager allows a seperation of
* components with gaps. The vertical gap will
* specify the space between rows and between the
* the rows and the borders of the <code>Container</code>.
*
* @serial
* @see #getHgap()
* @see #setHgap(int)
*/
int vgap;
/**
* If true, components will be aligned on their baseline.
*/
private boolean alignOnBaseline;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -7262534875583282631L;
/**
* Constructs a new <code>FlowLayout</code> with a centered alignment and a
* default 5-unit horizontal and vertical gap.
*/
public FlowLayout() {
this(CENTER, 5, 5);
}
/**
* Constructs a new <code>FlowLayout</code> with the specified
* alignment and a default 5-unit horizontal and vertical gap.
* The value of the alignment argument must be one of
* <code>FlowLayout.LEFT</code>, <code>FlowLayout.RIGHT</code>,
* <code>FlowLayout.CENTER</code>, <code>FlowLayout.LEADING</code>,
* or <code>FlowLayout.TRAILING</code>.
* @param align the alignment value
*/
public FlowLayout(int align) {
this(align, 5, 5);
}
/**
* Creates a new flow layout manager with the indicated alignment
* and the indicated horizontal and vertical gaps.
* <p>
* The value of the alignment argument must be one of
* <code>FlowLayout.LEFT</code>, <code>FlowLayout.RIGHT</code>,
* <code>FlowLayout.CENTER</code>, <code>FlowLayout.LEADING</code>,
* or <code>FlowLayout.TRAILING</code>.
* @param align the alignment value
* @param hgap the horizontal gap between components
* and between the components and the
* borders of the <code>Container</code>
* @param vgap the vertical gap between components
* and between the components and the
* borders of the <code>Container</code>
*/
public FlowLayout(int align, int hgap, int vgap) {
this.hgap = hgap;
this.vgap = vgap;
setAlignment(align);
}
/**
* Gets the alignment for this layout.
* Possible values are <code>FlowLayout.LEFT</code>,
* <code>FlowLayout.RIGHT</code>, <code>FlowLayout.CENTER</code>,
* <code>FlowLayout.LEADING</code>,
* or <code>FlowLayout.TRAILING</code>.
* @return the alignment value for this layout
* @see java.awt.FlowLayout#setAlignment
* @since JDK1.1
*/
public int getAlignment() {
return newAlign;
}
/**
* Sets the alignment for this layout.
* Possible values are
* <ul>
* <li><code>FlowLayout.LEFT</code>
* <li><code>FlowLayout.RIGHT</code>
* <li><code>FlowLayout.CENTER</code>
* <li><code>FlowLayout.LEADING</code>
* <li><code>FlowLayout.TRAILING</code>
* </ul>
* @param align one of the alignment values shown above
* @see #getAlignment()
* @since JDK1.1
*/
public void setAlignment(int align) {
this.newAlign = align;
// this.align is used only for serialization compatibility,
// so set it to a value compatible with the 1.1 version
// of the class
switch (align) {
case LEADING:
this.align = LEFT;
break;
case TRAILING:
this.align = RIGHT;
break;
default:
this.align = align;
break;
}
}
/**
* Gets the horizontal gap between components
* and between the components and the borders
* of the <code>Container</code>
*
* @return the horizontal gap between components
* and between the components and the borders
* of the <code>Container</code>
* @see java.awt.FlowLayout#setHgap
* @since JDK1.1
*/
public int getHgap() {
return hgap;
}
/**
* Sets the horizontal gap between components and
* between the components and the borders of the
* <code>Container</code>.
*
* @param hgap the horizontal gap between components
* and between the components and the borders
* of the <code>Container</code>
* @see java.awt.FlowLayout#getHgap
* @since JDK1.1
*/
public void setHgap(int hgap) {
this.hgap = hgap;
}
/**
* Gets the vertical gap between components and
* between the components and the borders of the
* <code>Container</code>.
*
* @return the vertical gap between components
* and between the components and the borders
* of the <code>Container</code>
* @see java.awt.FlowLayout#setVgap
* @since JDK1.1
*/
public int getVgap() {
return vgap;
}
/**
* Sets the vertical gap between components and between
* the components and the borders of the <code>Container</code>.
*
* @param vgap the vertical gap between components
* and between the components and the borders
* of the <code>Container</code>
* @see java.awt.FlowLayout#getVgap
* @since JDK1.1
*/
public void setVgap(int vgap) {
this.vgap = vgap;
}
/**
* Sets whether or not components should be vertically aligned along their
* baseline. Components that do not have a baseline will be centered.
* The default is false.
*
* @param alignOnBaseline whether or not components should be
* vertically aligned on their baseline
* @since 1.6
*/
public void setAlignOnBaseline(boolean alignOnBaseline) {
this.alignOnBaseline = alignOnBaseline;
}
/**
* Returns true if components are to be vertically aligned along
* their baseline. The default is false.
*
* @return true if components are to be vertically aligned along
* their baseline
* @since 1.6
*/
public boolean getAlignOnBaseline() {
return alignOnBaseline;
}
/**
* Adds the specified component to the layout.
* Not used by this class.
* @param name the name of the component
* @param comp the component to be added
*/
public void addLayoutComponent(String name, Component comp) {
}
/**
* Removes the specified component from the layout.
* Not used by this class.
* @param comp the component to remove
* @see java.awt.Container#removeAll
*/
public void removeLayoutComponent(Component comp) {
}
/**
* Returns the preferred dimensions for this layout given the
* <i>visible</i> components in the specified target container.
*
* @param target the container that needs to be laid out
* @return the preferred dimensions to lay out the
* subcomponents of the specified container
* @see Container
* @see #minimumLayoutSize
* @see java.awt.Container#getPreferredSize
*/
public Dimension preferredLayoutSize(Container target) {
Dimension dim = new Dimension(0, 0);
int nmembers = target.getComponentCount();
boolean firstVisibleComponent = true;
boolean useBaseline = getAlignOnBaseline();
int maxAscent = 0;
int maxDescent = 0;
for (int i = 0 ; i < nmembers ; i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
dim.height = Math.max(dim.height, d.height);
if (firstVisibleComponent) {
firstVisibleComponent = false;
} else {
dim.width += hgap;
}
dim.width += d.width;
if (useBaseline) {
int baseline = m.getBaseline(d.width, d.height);
if (baseline >= 0) {
maxAscent = Math.max(maxAscent, baseline);
maxDescent = Math.max(maxDescent, d.height - baseline);
}
}
}
}
if (useBaseline) {
dim.height = Math.max(maxAscent + maxDescent, dim.height);
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right + hgap*2;
dim.height += insets.top + insets.bottom + vgap*2;
return dim;
}
/**
* Returns the minimum dimensions needed to layout the <i>visible</i>
* components contained in the specified target container.
* @param target the container that needs to be laid out
* @return the minimum dimensions to lay out the
* subcomponents of the specified container
* @see #preferredLayoutSize
* @see java.awt.Container
* @see java.awt.Container#doLayout
*/
public Dimension minimumLayoutSize(Container target) {
boolean useBaseline = getAlignOnBaseline();
Dimension dim = new Dimension(0, 0);
int nmembers = target.getComponentCount();
int maxAscent = 0;
int maxDescent = 0;
boolean firstVisibleComponent = true;
for (int i = 0 ; i < nmembers ; i++) {
Component m = target.getComponent(i);
if (m.visible) {
Dimension d = m.getMinimumSize();
dim.height = Math.max(dim.height, d.height);
if (firstVisibleComponent) {
firstVisibleComponent = false;
} else {
dim.width += hgap;
}
dim.width += d.width;
if (useBaseline) {
int baseline = m.getBaseline(d.width, d.height);
if (baseline >= 0) {
maxAscent = Math.max(maxAscent, baseline);
maxDescent = Math.max(maxDescent,
dim.height - baseline);
}
}
}
}
if (useBaseline) {
dim.height = Math.max(maxAscent + maxDescent, dim.height);
}
Insets insets = target.getInsets();
dim.width += insets.left + insets.right + hgap*2;
dim.height += insets.top + insets.bottom + vgap*2;
return dim;
}
/**
* Centers the elements in the specified row, if there is any slack.
* @param target the component which needs to be moved
* @param x the x coordinate
* @param y the y coordinate
* @param width the width dimensions
* @param height the height dimensions
* @param rowStart the beginning of the row
* @param rowEnd the the ending of the row
* @param useBaseline Whether or not to align on baseline.
* @param ascent Ascent for the components. This is only valid if
* useBaseline is true.
* @param descent Ascent for the components. This is only valid if
* useBaseline is true.
* @return actual row height
*/
private int moveComponents(Container target, int x, int y, int width, int height,
int rowStart, int rowEnd, boolean ltr,
boolean useBaseline, int[] ascent,
int[] descent) {
switch (newAlign) {
case LEFT:
x += ltr ? 0 : width;
break;
case CENTER:
x += width / 2;
break;
case RIGHT:
x += ltr ? width : 0;
break;
case LEADING:
break;
case TRAILING:
x += width;
break;
}
int maxAscent = 0;
int nonbaselineHeight = 0;
int baselineOffset = 0;
if (useBaseline) {
int maxDescent = 0;
for (int i = rowStart ; i < rowEnd ; i++) {
Component m = target.getComponent(i);
if (m.visible) {
if (ascent[i] >= 0) {
maxAscent = Math.max(maxAscent, ascent[i]);
maxDescent = Math.max(maxDescent, descent[i]);
}
else {
nonbaselineHeight = Math.max(m.getHeight(),
nonbaselineHeight);
}
}
}
height = Math.max(maxAscent + maxDescent, nonbaselineHeight);
baselineOffset = (height - maxAscent - maxDescent) / 2;
}
for (int i = rowStart ; i < rowEnd ; i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
int cy;
if (useBaseline && ascent[i] >= 0) {
cy = y + baselineOffset + maxAscent - ascent[i];
}
else {
cy = y + (height - m.getHeight()) / 2;
}
if (ltr) {
m.setLocation(x, cy);
} else {
m.setLocation(target.getWidth() - x - m.getWidth(), cy);
}
x += m.getWidth() + hgap;
}
}
return height;
}
/**
* Lays out the container. This method lets each
* <i>visible</i> component take
* its preferred size by reshaping the components in the
* target container in order to satisfy the alignment of
* this <code>FlowLayout</code> object.
*
* @param target the specified component being laid out
* @see Container
* @see java.awt.Container#doLayout
*/
public void layoutContainer(Container target) {
Insets insets = target.getInsets();
int maxwidth = target.getWidth() - (insets.left + insets.right + hgap*2);
int nmembers = target.getComponentCount();
int x = 0, y = insets.top + vgap;
int rowh = 0, start = 0;
boolean ltr = target.getComponentOrientation().isLeftToRight();
boolean useBaseline = getAlignOnBaseline();
int[] ascent = null;
int[] descent = null;
if (useBaseline) {
ascent = new int[nmembers];
descent = new int[nmembers];
}
for (int i = 0 ; i < nmembers ; i++) {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = m.getPreferredSize();
m.setSize(d.width, d.height);
if (useBaseline) {
int baseline = m.getBaseline(d.width, d.height);
if (baseline >= 0) {
ascent[i] = baseline;
descent[i] = d.height - baseline;
}
else {
ascent[i] = -1;
}
}
if ((x == 0) || ((x + d.width) <= maxwidth)) {
if (x > 0) {
x += hgap;
}
x += d.width;
rowh = Math.max(rowh, d.height);
} else {
rowh = moveComponents(target, insets.left + hgap, y,
maxwidth - x, rowh, start, i, ltr,
useBaseline, ascent, descent);
x = d.width;
y += vgap + rowh;
rowh = d.height;
start = i;
}
}
}
moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh,
start, nmembers, ltr, useBaseline, ascent, descent);
}
//
// the internal serial version which says which version was written
// - 0 (default) for versions before the Java 2 platform, v1.2
// - 1 for version >= Java 2 platform v1.2, which includes "newAlign" field
//
private static final int currentSerialVersion = 1;
/**
* This represent the <code>currentSerialVersion</code>
* which is bein used. It will be one of two values :
* <code>0</code> versions before Java 2 platform v1.2..
* <code>1</code> versions after Java 2 platform v1.2..
*
* @serial
* @since 1.2
*/
private int serialVersionOnStream = currentSerialVersion;
/**
* Reads this object out of a serialization stream, handling
* objects written by older versions of the class that didn't contain all
* of the fields we use now..
*/
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException
{
stream.defaultReadObject();
if (serialVersionOnStream < 1) {
// "newAlign" field wasn't present, so use the old "align" field.
setAlignment(this.align);
}
serialVersionOnStream = currentSerialVersion;
}
/**
* Returns a string representation of this <code>FlowLayout</code>
* object and its values.
* @return a string representation of this layout
*/
public String toString() {
String str = "";
switch (align) {
case LEFT: str = ",align=left"; break;
case CENTER: str = ",align=center"; break;
case RIGHT: str = ",align=right"; break;
case LEADING: str = ",align=leading"; break;
case TRAILING: str = ",align=trailing"; break;
}
return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + str + "]";
}
}
+244
View File
@@ -0,0 +1,244 @@
package java.awt;
import java.awt.font.*;
import java.awt.geom.*;
import java.io.*;
import java.util.*;
import java.text.AttributedCharacterIterator.Attribute;
public class Font implements Serializable
{
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = -4206021311591459213L;
/**
* The Constant PLAIN indicates font's plain style.
*/
public static final int PLAIN = 0;
/**
* The Constant BOLD indicates font's bold style.
*/
public static final int BOLD = 1;
/**
* The Constant ITALIC indicates font's italic style.
*/
public static final int ITALIC = 2;
/**
* The Constant ROMAN_BASELINE indicated roman baseline.
*/
public static final int ROMAN_BASELINE = 0;
/**
* The Constant CENTER_BASELINE indicates center baseline.
*/
public static final int CENTER_BASELINE = 1;
/**
* The Constant HANGING_BASELINE indicates hanging baseline.
*/
public static final int HANGING_BASELINE = 2;
/**
* The Constant TRUETYPE_FONT indicates a font resource of type TRUETYPE.
*/
public static final int TRUETYPE_FONT = 0;
/**
* The Constant TYPE1_FONT indicates a font resource of type TYPE1.
*/
public static final int TYPE1_FONT = 1;
/**
* The Constant LAYOUT_LEFT_TO_RIGHT indicates that text is left to right.
*/
public static final int LAYOUT_LEFT_TO_RIGHT = 0;
/**
* The Constant LAYOUT_RIGHT_TO_LEFT indicates that text is right to left.
*/
public static final int LAYOUT_RIGHT_TO_LEFT = 1;
/**
* The Constant LAYOUT_NO_START_CONTEXT indicates that the text in the char
* array before the indicated start should not be examined.
*/
public static final int LAYOUT_NO_START_CONTEXT = 2;
/**
* The Constant LAYOUT_NO_LIMIT_CONTEXT indicates that text in the char
* array after the indicated limit should not be examined.
*/
public static final int LAYOUT_NO_LIMIT_CONTEXT = 4;
/**
* The Constant DEFAULT_FONT.
*/
static final Font DEFAULT_FONT = new Font("Dialog", Font.PLAIN, 12); //$NON-NLS-1$
/**
* The name of the Font.
*/
protected String name;
/**
* The style of the Font.
*/
protected int style;
/**
* The size of the Font.
*/
protected int size;
/**
* The point size of the Font.
*/
protected float pointSize;
// Flag if the Font object transformed
/**
* The transformed.
*/
private boolean transformed;
// Set of font attributes
/**
* The requested attributes.
*/
private Hashtable<Attribute, Object> fRequestedAttributes;
// number of glyphs in this Font
/**
* The num glyphs.
*/
private transient int numGlyphs = -1;
// code for missing glyph for this Font
/**
* The missing glyph code.
*/
private transient int missingGlyphCode = -1;
/**
* Instantiates a new Font with the specified attributes. The Font will be
* created with default attributes if the attribute's parameter is null.
*
* @param attributes
* the attributes to be assigned to the new Font, or null.
*/
public Font(Map<? extends Attribute, ?> attributes) {
Object currAttr;
// Default values are taken from the documentation of the Font class.
// See Font constructor, decode and getFont sections.
this.name = "default"; //$NON-NLS-1$
this.size = 12;
this.pointSize = 12;
this.style = Font.PLAIN;
if (attributes != null) {
fRequestedAttributes = new Hashtable<Attribute, Object>(attributes);
currAttr = attributes.get(TextAttribute.SIZE);
if (currAttr != null) {
this.pointSize = ((Float)currAttr).floatValue();
this.size = (int)Math.ceil(this.pointSize);
}
currAttr = attributes.get(TextAttribute.POSTURE);
if (currAttr != null && currAttr.equals(TextAttribute.POSTURE_OBLIQUE)) {
this.style |= Font.ITALIC;
}
currAttr = attributes.get(TextAttribute.WEIGHT);
if ((currAttr != null)
&& (((Float)currAttr).floatValue() >= (TextAttribute.WEIGHT_BOLD).floatValue())) {
this.style |= Font.BOLD;
}
currAttr = attributes.get(TextAttribute.FAMILY);
if (currAttr != null) {
this.name = (String)currAttr;
}
currAttr = attributes.get(TextAttribute.TRANSFORM);
if (currAttr != null) {
/*
if (currAttr instanceof TransformAttribute) {
this.transformed = !((TransformAttribute)currAttr).getTransform().isIdentity();
} else
*/
if (currAttr instanceof AffineTransform) {
this.transformed = !((AffineTransform)currAttr).isIdentity();
}
}
} else {
fRequestedAttributes = new Hashtable<Attribute, Object>(5);
this.transformed = false;
fRequestedAttributes.put(TextAttribute.FAMILY, name);
fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
if ((this.style & Font.BOLD) != 0) {
fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
} else {
fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
}
if ((this.style & Font.ITALIC) != 0) {
fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
} else {
fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
}
}
}
/**
* Instantiates a new Font with the specified name, style and size.
*
* @param name
* the name of font.
* @param style
* the style of font.
* @param size
* the size of font.
*/
public Font(String name, int style, int size) {
this.name = (name != null) ? name : "Default"; //$NON-NLS-1$
this.size = (size >= 0) ? size : 0;
this.style = (style & ~0x03) == 0 ? style : Font.PLAIN;
this.pointSize = this.size;
fRequestedAttributes = new Hashtable<Attribute, Object>(5);
// fRequestedAttributes.put(TextAttribute.TRANSFORM, IDENTITY_TRANSFORM);
this.transformed = false;
fRequestedAttributes.put(TextAttribute.FAMILY, this.name);
fRequestedAttributes.put(TextAttribute.SIZE, new Float(this.size));
if ((this.style & Font.BOLD) != 0) {
fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
} else {
fRequestedAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_REGULAR);
}
if ((this.style & Font.ITALIC) != 0) {
fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
} else {
fRequestedAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_REGULAR);
}
}
}
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Ilya S. Okomin
* @version $Revision$
*/
package java.awt;
/**
* The FontFormatException class is used to provide notification and information
* that font can't be created.
*
* @since Android 1.0
*/
public class FontFormatException extends Exception {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = -4481290147811361272L;
/**
* Instantiates a new font format exception with detailed message.
*
* @param reason
* the detailed message.
*/
public FontFormatException(String reason) {
super(reason);
}
}
+37
View File
@@ -0,0 +1,37 @@
package java.awt;
import java.awt.*;
import java.util.*;
import java.awt.event.*;
public class Frame extends Window {
public Frame() {
super();
}
public Frame(String title) {
super(title);
}
public static Frame[] getFrames() {
Window[] allWindows = Window.getWindows();
List<Frame> frames = new ArrayList<Frame>();
for (Window w : allWindows) {
if (w instanceof Frame) {
frames.add((Frame) w);
}
}
return frames.toArray(new Frame[0]);
}
public void setLocationRelativeTo(Component comp) {
//super.setLocationRelativeTo(comp);
}
public void addWindowListener(WindowListener listener) {
//super.addWindowListener(lisener);
}
}
+42
View File
@@ -0,0 +1,42 @@
package java.awt;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import android.graphics.Canvas;
import android.graphics.Paint;
public class Graphics {
private Paint androidPaint;
private Canvas androidCanvas;
private BufferedImage bufImage;
public Graphics(BufferedImage bufImage) {
this.bufImage = bufImage;
this.androidCanvas = new Canvas(bufImage.getAndroidBitmap());
this.androidPaint = new Paint();
}
public void setColor(Color color) {
androidPaint.setColor(color.hashCode());
}
public void fillRect(int x, int y, int width, int height) {
this.androidCanvas.drawRect(x, y, x + width, y + height, androidPaint);
}
public void drawString(String s, int x, int y) {
this.androidCanvas.drawText(s, x, y, androidPaint);
}
public void dispose() {
}
public boolean drawImage(Image image, int x, int y, ImageObserver observer) {
if (image instanceof BufferedImage) {
this.androidCanvas.drawBitmap(((BufferedImage) image).getAndroidBitmap(), (float) x, (float) y, null);
}
return true;
}
}
@@ -0,0 +1,10 @@
package java.awt;
import java.awt.image.BufferedImage;
public class Graphics2D extends Graphics {
public Graphics2D(BufferedImage bufImage) {
super(bufImage);
}
}
@@ -0,0 +1,27 @@
package java.awt;
/*
* A fake GraphicsEnvironment, it was added
* for AWT codes compatible and do nothing.
*/
public class GraphicsEnvironment extends Object
{
private static GraphicsEnvironment localEnv = new GraphicsEnvironment();
public static GraphicsEnvironment getLocalGraphicsEnvironment() {
return localEnv;
}
public static String getHeadlessMessage() {
return
"\nNo X11 DISPLAY variable was set, " +
"but this program performed an operation which requires it.";
}
public static void checkHeadless() {
}
public static boolean isHeadless() {
return false;
}
}
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt;
/**
* Thrown when code that is dependent on a keyboard, display, or mouse
* is called in an environment that does not support a keyboard, display,
* or mouse.
*
* @since 1.4
* @author Michael Martak
*/
public class HeadlessException extends UnsupportedOperationException {
/*
* JDK 1.4 serialVersionUID
*/
private static final long serialVersionUID = 167183644944358563L;
public HeadlessException() {}
public HeadlessException(String msg) {
super(msg);
}
public String getMessage() {
String superMessage = super.getMessage();
String headlessMessage = GraphicsEnvironment.getHeadlessMessage();
if (superMessage == null) {
return headlessMessage;
} else if (headlessMessage == null) {
return superMessage;
} else {
return superMessage + headlessMessage;
}
}
}
@@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Michael Danilov
* @version $Revision$
*/
package java.awt;
/**
* The IllegalComponentStateException class is used to provide notification that
* AWT component is not in an appropriate state for the requested operation.
*
* @since Android 1.0
*/
public class IllegalComponentStateException extends IllegalStateException {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = -1889339587208144238L;
/**
* Instantiates a new IllegalComponentStateException with the specified
* message.
*
* @param s
* the String message which describes the exception.
*/
public IllegalComponentStateException(String s) {
super(s);
}
/**
* Instantiates a new IllegalComponentStateException without detailed
* message.
*/
public IllegalComponentStateException() {
}
}
+6
View File
@@ -0,0 +1,6 @@
package java.awt;
public abstract class Image
{
// MOD: Fake class.
}
+179
View File
@@ -0,0 +1,179 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Dmitry A. Durnev
* @version $Revision$
*/
package java.awt;
import java.io.Serializable;
import org.apache.harmony.misc.HashCode;
/**
* The Insets class represents the borders of a container. This class describes
* the space that a container should leave at each edge: the top, the bottom,
* the right side, and the left side. The space can be filled with a border, a
* blank space, or a title.
*
* @since Android 1.0
*/
public class Insets implements Cloneable, Serializable {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = -2272572637695466749L;
/**
* The top inset indicates the size of the space added to the top of the
* rectangle.
*/
public int top;
/**
* The left inset indicates the size of the space added to the left side of
* the rectangle.
*/
public int left;
/**
* The bottom inset indicates the size of the space subtracted from the
* bottom of the rectangle.
*/
public int bottom;
/**
* The right inset indicates the size of the space subtracted from the right
* side of the rectangle.
*/
public int right;
/**
* Instantiates a new Inset object with the specified top, left, bottom,
* right parameters.
*
* @param top
* the top inset.
* @param left
* the left inset.
* @param bottom
* the bottom inset.
* @param right
* the right inset.
*/
public Insets(int top, int left, int bottom, int right) {
setValues(top, left, bottom, right);
}
/**
* Returns a hash code of the Insets object.
*
* @return a hash code of the Insets object.
*/
@Override
public int hashCode() {
int hashCode = HashCode.EMPTY_HASH_CODE;
hashCode = HashCode.combine(hashCode, top);
hashCode = HashCode.combine(hashCode, left);
hashCode = HashCode.combine(hashCode, bottom);
hashCode = HashCode.combine(hashCode, right);
return hashCode;
}
/**
* Returns a copy of this Insets object.
*
* @return a copy of this Insets object.
*/
@Override
public Object clone() {
return new Insets(top, left, bottom, right);
}
/**
* Checks if this Insets object is equal to the specified object.
*
* @param o
* the Object to be compared.
* @return true, if the object is an Insets object whose data values are
* equal to those of this object, false otherwise.
*/
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (o instanceof Insets) {
Insets i = (Insets)o;
return ((i.left == left) && (i.bottom == bottom) && (i.right == right) && (i.top == top));
}
return false;
}
/**
* Returns a String representation of this Insets object.
*
* @return a String representation of this Insets object.
*/
@Override
public String toString() {
/*
* The format is based on 1.5 release behavior which can be revealed by
* the following code: System.out.println(new Insets(1, 2, 3, 4));
*/
return (getClass().getName() + "[left=" + left + ",top=" + top + //$NON-NLS-1$ //$NON-NLS-2$
",right=" + right + ",bottom=" + bottom + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
* Sets top, left, bottom, and right insets to the specified values.
*
* @param top
* the top inset.
* @param left
* the left inset.
* @param bottom
* the bottom inset.
* @param right
* the right inset.
*/
public void set(int top, int left, int bottom, int right) {
setValues(top, left, bottom, right);
}
/**
* Sets the values.
*
* @param top
* the top.
* @param left
* the left.
* @param bottom
* the bottom.
* @param right
* the right.
*/
private void setValues(int top, int left, int bottom, int right) {
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
}
}
@@ -0,0 +1,83 @@
/*
* Copyright (c) 1995, 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt;
/**
* Defines the interface for classes that know how to lay out
* <code>Container</code>s.
* <p>
* Swing's painting architecture assumes the children of a
* <code>JComponent</code> do not overlap. If a
* <code>JComponent</code>'s <code>LayoutManager</code> allows
* children to overlap, the <code>JComponent</code> must override
* <code>isOptimizedDrawingEnabled</code> to return false.
*
* @see Container
* @see javax.swing.JComponent#isOptimizedDrawingEnabled
*
* @author Sami Shaio
* @author Arthur van Hoff
*/
public interface LayoutManager {
/**
* If the layout manager uses a per-component string,
* adds the component <code>comp</code> to the layout,
* associating it
* with the string specified by <code>name</code>.
*
* @param name the string to be associated with the component
* @param comp the component to be added
*/
void addLayoutComponent(String name, Component comp);
/**
* Removes the specified component from the layout.
* @param comp the component to be removed
*/
void removeLayoutComponent(Component comp);
/**
* Calculates the preferred size dimensions for the specified
* container, given the components it contains.
* @param parent the container to be laid out
*
* @see #minimumLayoutSize
*/
Dimension preferredLayoutSize(Container parent);
/**
* Calculates the minimum size dimensions for the specified
* container, given the components it contains.
* @param parent the component to be laid out
* @see #preferredLayoutSize
*/
Dimension minimumLayoutSize(Container parent);
/**
* Lays out the specified container.
* @param parent the container to be laid out
*/
void layoutContainer(Container parent);
}
@@ -0,0 +1,87 @@
/*
* Copyright (c) 1996, 2001, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt;
/**
* Defines an interface for classes that know how to layout Containers
* based on a layout constraints object.
*
* This interface extends the LayoutManager interface to deal with layouts
* explicitly in terms of constraint objects that specify how and where
* components should be added to the layout.
* <p>
* This minimal extension to LayoutManager is intended for tool
* providers who wish to the creation of constraint-based layouts.
* It does not yet provide full, general support for custom
* constraint-based layout managers.
*
* @see LayoutManager
* @see Container
*
* @author Jonni Kanerva
*/
public interface LayoutManager2 extends LayoutManager {
/**
* Adds the specified component to the layout, using the specified
* constraint object.
* @param comp the component to be added
* @param constraints where/how the component is added to the layout.
*/
void addLayoutComponent(Component comp, Object constraints);
/**
* Calculates the maximum size dimensions for the specified container,
* given the components it contains.
* @see java.awt.Component#getMaximumSize
* @see LayoutManager
*/
public Dimension maximumLayoutSize(Container target);
/**
* Returns the alignment along the x axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentX(Container target);
/**
* Returns the alignment along the y axis. This specifies how
* the component would like to be aligned relative to other
* components. The value should be a number between 0 and 1
* where 0 represents alignment along the origin, 1 is aligned
* the furthest away from the origin, 0.5 is centered, etc.
*/
public float getLayoutAlignmentY(Container target);
/**
* Invalidates the layout, indicating that if the layout manager
* has cached information it should be discarded.
*/
public void invalidateLayout(Container target);
}
+148
View File
@@ -0,0 +1,148 @@
/*
* Copyright (c) 1995, 2007, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt;
import javax.accessibility.*;
/**
* <code>Panel</code> is the simplest container class. A panel
* provides space in which an application can attach any other
* component, including other panels.
* <p>
* The default layout manager for a panel is the
* <code>FlowLayout</code> layout manager.
*
* @author Sami Shaio
* @see java.awt.FlowLayout
* @since JDK1.0
*/
public class Panel extends Container implements Accessible {
private static final String base = "panel";
private static int nameCounter = 0;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -2728009084054400034L;
/**
* Creates a new panel using the default layout manager.
* The default layout manager for all panels is the
* <code>FlowLayout</code> class.
*/
public Panel() {
this(new FlowLayout());
}
/*
* MOD: Why this implements Accessible?
* So MOD adding below...
*/
@Override
public AccessibleContext getAccessibleContext()
{
// TODO: Implement this method
return null;
}
/**
* Creates a new panel with the specified layout manager.
* @param layout the layout manager for this panel.
* @since JDK1.1
*/
public Panel(LayoutManager layout) {
setLayout(layout);
}
/**
* Construct a name for this component. Called by getName() when the
* name is null.
*/
String constructComponentName() {
synchronized (Panel.class) {
return base + nameCounter++;
}
}
/**
* Creates the Panel's peer. The peer allows you to modify the
* appearance of the panel without changing its functionality.
*/
public void addNotify() {
super.addNotify();
/*
if (peer == null)
peer = getToolkit().createPanel(this);
*/
}
/////////////////
// Accessibility support
////////////////
/**
* Gets the AccessibleContext associated with this Panel.
* For panels, the AccessibleContext takes the form of an
* AccessibleAWTPanel.
* A new AccessibleAWTPanel instance is created if necessary.
*
* @return an AccessibleAWTPanel that serves as the
* AccessibleContext of this Panel
* @since 1.3
*/
/*
public AccessibleContext getAccessibleContext() {
if (accessibleContext == null) {
accessibleContext = new AccessibleAWTPanel();
}
return accessibleContext;
}
*/
/**
* This class implements accessibility support for the
* <code>Panel</code> class. It provides an implementation of the
* Java Accessibility API appropriate to panel user-interface elements.
* @since 1.3
*/
protected class AccessibleAWTPanel { // extends AccessibleAWTContainer {
private static final long serialVersionUID = -6409552226660031050L;
/**
* Get the role of this object.
*
* @return an instance of AccessibleRole describing the role of the
* object
*/
/*
public AccessibleRole getAccessibleRole() {
return AccessibleRole.PANEL;
}
*/
}
}
+211
View File
@@ -0,0 +1,211 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt;
import java.awt.geom.Point2D;
import java.io.Serializable;
/**
* The Point class represents a point location with coordinates X, Y in current
* coordinate system.
*
* @since Android 1.0
*/
public class Point extends Point2D implements Serializable {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = -5276940640259749850L;
/**
* The X coordinate of Point.
*/
public int x;
/**
* The Y coordinate of Point.
*/
public int y;
/**
* Instantiates a new point with (0, O) coordinates, the origin of
* coordinate system.
*/
public Point() {
setLocation(0, 0);
}
/**
* Instantiates a new point with (x, y) coordinates.
*
* @param x
* the X coordinate of Point.
* @param y
* the Y coordinate of Point.
*/
public Point(int x, int y) {
setLocation(x, y);
}
/**
* Instantiates a new point, giving it the same location as the parameter p.
*
* @param p
* the Point object giving the coordinates of the new point.
*/
public Point(Point p) {
setLocation(p.x, p.y);
}
/**
* Compares current Point with the specified object.
*
* @param obj
* the Object to be compared.
* @return true, if the Object being compared is a Point whose coordinates
* are equal to the coordinates of this Point, false otherwise.
* @see java.awt.geom.Point2D#equals(Object)
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Point) {
Point p = (Point)obj;
return x == p.x && y == p.y;
}
return false;
}
/**
* Returns string representation of the current Point object.
*
* @return a string representation of the current Point object.
*/
@Override
public String toString() {
return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
/**
* Gets X coordinate of Point as a double.
*
* @return X coordinate of the point as a double.
* @see java.awt.geom.Point2D#getX()
*/
@Override
public double getX() {
return x;
}
/**
* Gets Y coordinate of Point as a double.
*
* @return Y coordinate of the point as a double.
* @see java.awt.geom.Point2D#getY()
*/
@Override
public double getY() {
return y;
}
/**
* Gets the location of the Point as a new Point object.
*
* @return a copy of the Point.
*/
public Point getLocation() {
return new Point(x, y);
}
/**
* Sets the location of the Point to the same coordinates as p.
*
* @param p
* the Point that gives the new location.
*/
public void setLocation(Point p) {
setLocation(p.x, p.y);
}
/**
* Sets the location of the Point to the coordinates X, Y.
*
* @param x
* the X coordinate of the Point's new location.
* @param y
* the Y coordinate of the Point's new location.
*/
public void setLocation(int x, int y) {
this.x = x;
this.y = y;
}
/**
* Sets the location of Point to the specified double coordinates.
*
* @param x
* the X the Point's new location.
* @param y
* the Y the Point's new location.
* @see java.awt.geom.Point2D#setLocation(double, double)
*/
@Override
public void setLocation(double x, double y) {
x = x < Integer.MIN_VALUE ? Integer.MIN_VALUE : x > Integer.MAX_VALUE ? Integer.MAX_VALUE
: x;
y = y < Integer.MIN_VALUE ? Integer.MIN_VALUE : y > Integer.MAX_VALUE ? Integer.MAX_VALUE
: y;
setLocation((int)Math.round(x), (int)Math.round(y));
}
/**
* Moves the Point to the specified (x, y) location.
*
* @param x
* the X coordinate of the new location.
* @param y
* the Y coordinate of the new location.
*/
public void move(int x, int y) {
setLocation(x, y);
}
/**
* Translates current Point moving it from the position (x, y) to the new
* position given by (x+dx, x+dy) coordinates.
*
* @param dx
* the horizontal delta - the Point is moved to this distance
* along X axis.
* @param dy
* the vertical delta - the Point is moved to this distance along
* Y axis.
*/
public void translate(int dx, int dy) {
x += dx;
y += dy;
}
}
+723
View File
@@ -0,0 +1,723 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
/**
* The Rectangle class defines the rectangular area in terms of its upper left
* corner coordinates [x,y], its width, and its height. A Rectangle specified by
* [x, y, width, height] parameters has an outline path with corners at [x, y],
* [x + width,y], [x + width,y + height], and [x, y + height]. <br>
* <br>
* The rectangle is empty if the width or height is negative or zero. In this
* case the isEmpty method returns true.
*
* @since Android 1.0
*/
public class Rectangle extends Rectangle2D implements Shape, Serializable {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = -4345857070255674764L;
/**
* The X coordinate of the rectangle's left upper corner.
*/
public int x;
/**
* The Y coordinate of the rectangle's left upper corner.
*/
public int y;
/**
* The width of rectangle.
*/
public int width;
/**
* The height of rectangle.
*/
public int height;
/**
* Instantiates a new rectangle with [0, 0] upper left corner coordinates,
* the width and the height are zero.
*/
public Rectangle() {
setBounds(0, 0, 0, 0);
}
/**
* Instantiates a new rectangle whose upper left corner coordinates are
* given by the Point object (p.X and p.Y), and the width and the height are
* zero.
*
* @param p
* the Point specifies the upper left corner coordinates of the
* rectangle.
*/
public Rectangle(Point p) {
setBounds(p.x, p.y, 0, 0);
}
/**
* Instantiates a new rectangle whose upper left corner coordinates are
* given by the Point object (p.X and p.Y), and the width and the height are
* given by Dimension object (d.width and d.height).
*
* @param p
* the point specifies the upper left corner coordinates of the
* rectangle.
* @param d
* the dimension specifies the width and the height of the
* rectangle.
*/
public Rectangle(Point p, Dimension d) {
setBounds(p.x, p.y, d.width, d.height);
}
/**
* Instantiates a new rectangle determined by the upper left corner
* coordinates (x, y), width and height.
*
* @param x
* the X upper left corner coordinate of the rectangle.
* @param y
* the Y upper left corner coordinate of the rectangle.
* @param width
* the width of rectangle.
* @param height
* the height of rectangle.
*/
public Rectangle(int x, int y, int width, int height) {
setBounds(x, y, width, height);
}
/**
* Instantiates a new rectangle with [0, 0] as its upper left corner
* coordinates and the specified width and height.
*
* @param width
* the width of rectangle.
* @param height
* the height of rectangle.
*/
public Rectangle(int width, int height) {
setBounds(0, 0, width, height);
}
/**
* Instantiates a new rectangle with the same coordinates as the given
* source rectangle.
*
* @param r
* the Rectangle object which parameters will be used for
* instantiating a new Rectangle.
*/
public Rectangle(Rectangle r) {
setBounds(r.x, r.y, r.width, r.height);
}
/*
* public Rectangle(Dimension d) { setBounds(0, 0, d.width, d.height); }
*/
/**
* Gets the X coordinate of bound as a double.
*
* @return the X coordinate of bound as a double.
* @see java.awt.geom.RectangularShape#getX()
*/
@Override
public double getX() {
return x;
}
/**
* Gets the Y coordinate of bound as a double.
*
* @return the Y coordinate of bound as a double.
* @see java.awt.geom.RectangularShape#getY()
*/
@Override
public double getY() {
return y;
}
/**
* Gets the height of the rectangle as a double.
*
* @return the height of the rectangle as a double.
* @see java.awt.geom.RectangularShape#getHeight()
*/
@Override
public double getHeight() {
return height;
}
/**
* Gets the width of the rectangle as a double.
*
* @return the width of the rectangle as a double.
* @see java.awt.geom.RectangularShape#getWidth()
*/
@Override
public double getWidth() {
return width;
}
/**
* Determines whether or not the rectangle is empty. The rectangle is empty
* if its width or height is negative or zero.
*
* @return true, if the rectangle is empty, otherwise false.
* @see java.awt.geom.RectangularShape#isEmpty()
*/
@Override
public boolean isEmpty() {
return width <= 0 || height <= 0;
}
/**
* Gets the size of a Rectangle as Dimension object.
*
* @return a Dimension object which represents size of the rectangle.
*/
public Dimension getSize() {
return new Dimension(width, height);
}
/**
* Sets the size of the Rectangle.
*
* @param width
* the new width of the rectangle.
* @param height
* the new height of the rectangle.
*/
public void setSize(int width, int height) {
this.width = width;
this.height = height;
}
/**
* Sets the size of a Rectangle specified as Dimension object.
*
* @param d
* a Dimension object which represents new size of a rectangle.
*/
public void setSize(Dimension d) {
setSize(d.width, d.height);
}
/**
* Gets the location of a rectangle's upper left corner as a Point object.
*
* @return the Point object with coordinates equal to the upper left corner
* of the rectangle.
*/
public Point getLocation() {
return new Point(x, y);
}
/**
* Sets the location of the rectangle in terms of its upper left corner
* coordinates X and Y.
*
* @param x
* the X coordinate of the rectangle's upper left corner.
* @param y
* the Y coordinate of the rectangle's upper left corner.
*/
public void setLocation(int x, int y) {
this.x = x;
this.y = y;
}
/**
* Sets the location of a rectangle using a Point object to give the
* coordinates of the upper left corner.
*
* @param p
* the Point object which represents the new upper left corner
* coordinates of rectangle.
*/
public void setLocation(Point p) {
setLocation(p.x, p.y);
}
/**
* Moves a rectangle to the new location by moving its upper left corner to
* the point with coordinates X and Y.
*
* @param x
* the new X coordinate of the rectangle's upper left corner.
* @param y
* the new Y coordinate of the rectangle's upper left corner.
* @deprecated Use setLocation(int, int) method.
*/
@Deprecated
public void move(int x, int y) {
setLocation(x, y);
}
/**
* Sets the rectangle to be the nearest rectangle with integer coordinates
* bounding the rectangle defined by the double-valued parameters.
*
* @param x
* the X coordinate of the upper left corner of the double-valued
* rectangle to be bounded.
* @param y
* the Y coordinate of the upper left corner of the double-valued
* rectangle to be bounded.
* @param width
* the width of the rectangle to be bounded.
* @param height
* the height of the rectangle to be bounded.
* @see java.awt.geom.Rectangle2D#setRect(double, double, double, double)
*/
@Override
public void setRect(double x, double y, double width, double height) {
int x1 = (int)Math.floor(x);
int y1 = (int)Math.floor(y);
int x2 = (int)Math.ceil(x + width);
int y2 = (int)Math.ceil(y + height);
setBounds(x1, y1, x2 - x1, y2 - y1);
}
/**
* Sets a new size for the rectangle.
*
* @param width
* the rectangle's new width.
* @param height
* the rectangle's new height.
* @deprecated use the setSize(int, int) method.
*/
@Deprecated
public void resize(int width, int height) {
setBounds(x, y, width, height);
}
/**
* Resets the bounds of a rectangle to the specified x, y, width and height
* parameters.
*
* @param x
* the new X coordinate of the upper left corner.
* @param y
* the new Y coordinate of the upper left corner.
* @param width
* the new width of rectangle.
* @param height
* the new height of rectangle.
* @deprecated use setBounds(int, int, int, int) method
*/
@Deprecated
public void reshape(int x, int y, int width, int height) {
setBounds(x, y, width, height);
}
/**
* Gets bounds of the rectangle as a new Rectangle object.
*
* @return the Rectangle object with the same bounds as the original
* rectangle.
* @see java.awt.geom.RectangularShape#getBounds()
*/
@Override
public Rectangle getBounds() {
return new Rectangle(x, y, width, height);
}
/**
* Gets the bounds of the original rectangle as a Rectangle2D object.
*
* @return the Rectangle2D object which represents the bounds of the
* original rectangle.
* @see java.awt.geom.Rectangle2D#getBounds2D()
*/
@Override
public Rectangle2D getBounds2D() {
return getBounds();
}
/**
* Sets the bounds of a rectangle to the specified x, y, width, and height
* parameters.
*
* @param x
* the X coordinate of the upper left corner.
* @param y
* the Y coordinate of the upper left corner.
* @param width
* the width of rectangle.
* @param height
* the height of rectangle.
*/
public void setBounds(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.height = height;
this.width = width;
}
/**
* Sets the bounds of the rectangle to match the bounds of the Rectangle
* object sent as a parameter.
*
* @param r
* the Rectangle object which specifies the new bounds.
*/
public void setBounds(Rectangle r) {
setBounds(r.x, r.y, r.width, r.height);
}
/**
* Enlarges the rectangle by moving each corner outward from the center by a
* distance of dx horizonally and a distance of dy vertically. Specifically,
* changes a rectangle with [x, y, width, height] parameters to a rectangle
* with [x-dx, y-dy, width+2*dx, height+2*dy] parameters.
*
* @param dx
* the horizontal distance to move each corner coordinate.
* @param dy
* the vertical distance to move each corner coordinate.
*/
public void grow(int dx, int dy) {
x -= dx;
y -= dy;
width += dx + dx;
height += dy + dy;
}
/**
* Moves a rectangle a distance of mx along the x coordinate axis and a
* distance of my along y coordinate axis.
*
* @param mx
* the horizontal translation increment.
* @param my
* the vertical translation increment.
*/
public void translate(int mx, int my) {
x += mx;
y += my;
}
/**
* Enlarges the rectangle to cover the specified point.
*
* @param px
* the X coordinate of the new point to be covered by the
* rectangle.
* @param py
* the Y coordinate of the new point to be covered by the
* rectangle.
*/
public void add(int px, int py) {
int x1 = Math.min(x, px);
int x2 = Math.max(x + width, px);
int y1 = Math.min(y, py);
int y2 = Math.max(y + height, py);
setBounds(x1, y1, x2 - x1, y2 - y1);
}
/**
* Enlarges the rectangle to cover the specified point with the new point
* given as a Point object.
*
* @param p
* the Point object that specifies the new point to be covered by
* the rectangle.
*/
public void add(Point p) {
add(p.x, p.y);
}
/**
* Adds a new rectangle to the original rectangle, the result is an union of
* the specified specified rectangle and original rectangle.
*
* @param r
* the Rectangle which is added to the original rectangle.
*/
public void add(Rectangle r) {
int x1 = Math.min(x, r.x);
int x2 = Math.max(x + width, r.x + r.width);
int y1 = Math.min(y, r.y);
int y2 = Math.max(y + height, r.y + r.height);
setBounds(x1, y1, x2 - x1, y2 - y1);
}
/**
* Determines whether or not the point with specified coordinates [px, py]
* is within the bounds of the rectangle.
*
* @param px
* the X coordinate of point.
* @param py
* the Y coordinate of point.
* @return true, if the point with specified coordinates [px, py] is within
* the bounds of the rectangle, false otherwise.
*/
public boolean contains(int px, int py) {
if (isEmpty()) {
return false;
}
if (px < x || py < y) {
return false;
}
px -= x;
py -= y;
return px < width && py < height;
}
/**
* Determines whether or not the point given as a Point object is within the
* bounds of the rectangle.
*
* @param p
* the Point object
* @return true, if the point p is within the bounds of the rectangle,
* otherwise false.
*/
public boolean contains(Point p) {
return contains(p.x, p.y);
}
/**
* Determines whether or not the rectangle specified by [rx, ry, rw, rh]
* parameters is located inside the original rectangle.
*
* @param rx
* the X coordinate of the rectangle to compare.
* @param ry
* the Y coordinate of the rectangle to compare.
* @param rw
* the width of the rectangle to compare.
* @param rh
* the height of the rectangle to compare.
* @return true, if a rectangle with [rx, ry, rw, rh] parameters is entirely
* contained in the original rectangle, false otherwise.
*/
public boolean contains(int rx, int ry, int rw, int rh) {
return contains(rx, ry) && contains(rx + rw - 1, ry + rh - 1);
}
/**
* Compares whether or not the rectangle specified by the Rectangle object
* is located inside the original rectangle.
*
* @param r
* the Rectangle object.
* @return true, if the rectangle specified by Rectangle object is entirely
* contained in the original rectangle, false otherwise.
*/
public boolean contains(Rectangle r) {
return contains(r.x, r.y, r.width, r.height);
}
/**
* Compares whether or not a point with specified coordinates [px, py]
* belongs to a rectangle.
*
* @param px
* the X coordinate of a point.
* @param py
* the Y coordinate of a point.
* @return true, if a point with specified coordinates [px, py] belongs to a
* rectangle, otherwise false.
* @deprecated use contains(int, int) method.
*/
@Deprecated
public boolean inside(int px, int py) {
return contains(px, py);
}
/**
* Returns the intersection of the original rectangle with the specified
* Rectangle2D.
*
* @param r
* the Rectangle2D object.
* @return the Rectangle2D object that is the result of intersecting the
* original rectangle with the specified Rectangle2D.
* @see java.awt.geom.Rectangle2D#createIntersection(java.awt.geom.Rectangle2D)
*/
@Override
public Rectangle2D createIntersection(Rectangle2D r) {
if (r instanceof Rectangle) {
return intersection((Rectangle)r);
}
Rectangle2D dst = new Rectangle2D.Double();
Rectangle2D.intersect(this, r, dst);
return dst;
}
/**
* Returns the intersection of the original rectangle with the specified
* rectangle. An empty rectangle is returned if there is no intersection.
*
* @param r
* the Rectangle object.
* @return the Rectangle object is result of the original rectangle with the
* specified rectangle.
*/
public Rectangle intersection(Rectangle r) {
int x1 = Math.max(x, r.x);
int y1 = Math.max(y, r.y);
int x2 = Math.min(x + width, r.x + r.width);
int y2 = Math.min(y + height, r.y + r.height);
return new Rectangle(x1, y1, x2 - x1, y2 - y1);
}
/**
* Determines whether or not the original rectangle intersects the specified
* rectangle.
*
* @param r
* the Rectangle object.
* @return true, if the two rectangles overlap, false otherwise.
*/
public boolean intersects(Rectangle r) {
return !intersection(r).isEmpty();
}
/**
* Determines where the specified Point is located with respect to the
* rectangle. This method computes whether the point is to the right or to
* the left of the rectangle and whether it is above or below the rectangle,
* and packs the result into an integer by using a binary OR operation with
* the following masks:
* <ul>
*<li>Rectangle2D.OUT_LEFT</li>
*<li>Rectangle2D.OUT_TOP</li>
*<li>Rectangle2D.OUT_RIGHT</li>
*<li>Rectangle2D.OUT_BOTTOM</li>
*</ul>
* If the rectangle is empty, all masks are set, and if the point is inside
* the rectangle, none are set.
*
* @param px
* the X coordinate of the specified point.
* @param py
* the Y coordinate of the specified point.
* @return the location of the Point relative to the rectangle as the result
* of logical OR operation with all out masks.
* @see java.awt.geom.Rectangle2D#outcode(double, double)
*/
@Override
public int outcode(double px, double py) {
int code = 0;
if (width <= 0) {
code |= OUT_LEFT | OUT_RIGHT;
} else if (px < x) {
code |= OUT_LEFT;
} else if (px > x + width) {
code |= OUT_RIGHT;
}
if (height <= 0) {
code |= OUT_TOP | OUT_BOTTOM;
} else if (py < y) {
code |= OUT_TOP;
} else if (py > y + height) {
code |= OUT_BOTTOM;
}
return code;
}
/**
* Enlarges the rectangle to cover the specified Rectangle2D.
*
* @param r
* the Rectangle2D object.
* @return the union of the original and the specified Rectangle2D.
* @see java.awt.geom.Rectangle2D#createUnion(java.awt.geom.Rectangle2D)
*/
@Override
public Rectangle2D createUnion(Rectangle2D r) {
if (r instanceof Rectangle) {
return union((Rectangle)r);
}
Rectangle2D dst = new Rectangle2D.Double();
Rectangle2D.union(this, r, dst);
return dst;
}
/**
* Enlarges the rectangle to cover the specified rectangle.
*
* @param r
* the Rectangle.
* @return the union of the original and the specified rectangle.
*/
public Rectangle union(Rectangle r) {
Rectangle dst = new Rectangle(this);
dst.add(r);
return dst;
}
/**
* Compares the original Rectangle with the specified object.
*
* @param obj
* the specified Object for comparison.
* @return true, if the specified Object is a rectangle with the same
* dimensions as the original rectangle, false otherwise.
* @see java.awt.geom.Rectangle2D#equals(Object)
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Rectangle) {
Rectangle r = (Rectangle)obj;
return r.x == x && r.y == y && r.width == width && r.height == height;
}
return false;
}
/**
* Returns a string representation of the rectangle; the string contains [x,
* y, width, height] parameters of the rectangle.
*
* @return the string representation of the rectangle.
*/
@Override
public String toString() {
// The output format based on 1.5 release behaviour. It could be
// obtained in the following way
// System.out.println(new Rectangle().toString())
return getClass().getName() + "[x=" + x + ",y=" + y + //$NON-NLS-1$ //$NON-NLS-2$
",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
+162
View File
@@ -0,0 +1,162 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Alexey A. Petrenko
* @version $Revision$
*/
package java.awt;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
/**
* The Shape interface defines a geometric shape defined by a boundary (outline)
* path. The path outline can be accessed through a PathIterator object. The
* Shape interface provides methods for obtaining the bounding box (which is the
* smallest rectangle containing the shape and for obtaining a PathIterator
* object for current Shape, as well as utility methods which determine if the
* Shape contains or intersects a Rectangle or contains a Point.
*
* @since Android 1.0
*/
public interface Shape {
/**
* Checks whether or not the point with specified coordinates lies inside
* the Shape.
*
* @param x
* the X coordinate.
* @param y
* the Y coordinate.
* @return true, if the specified coordinates lie inside the Shape, false
* otherwise.
*/
public boolean contains(double x, double y);
/**
* Checks whether or not the rectangle with specified [x, y, width, height]
* parameters lies inside the Shape.
*
* @param x
* the X double coordinate of the rectangle's upper left corner.
* @param y
* the Y double coordinate of the rectangle's upper left corner.
* @param w
* the width of rectangle.
* @param h
* the height of rectangle.
* @return true, if the specified rectangle lies inside the Shape, false
* otherwise.
*/
public boolean contains(double x, double y, double w, double h);
/**
* Checks whether or not the specified Point2D lies inside the Shape.
*
* @param point
* the Point2D object.
* @return true, if the specified Point2D lies inside the Shape, false
* otherwise.
*/
public boolean contains(Point2D point);
/**
* Checks whether or not the specified rectangle lies inside the Shape.
*
* @param r
* the Rectangle2D object.
* @return true, if the specified rectangle lies inside the Shape, false
* otherwise.
*/
public boolean contains(Rectangle2D r);
/**
* Gets the bounding rectangle of the Shape. The bounding rectangle is the
* smallest rectangle which contains the Shape.
*
* @return the bounding rectangle of the Shape.
*/
public Rectangle getBounds();
/**
* Gets the Rectangle2D which represents Shape bounds. The bounding
* rectangle is the smallest rectangle which contains the Shape.
*
* @return the bounding rectangle of the Shape.
*/
public Rectangle2D getBounds2D();
/**
* Gets the PathIterator object of the Shape which provides access to the
* shape's boundary modified by the specified AffineTransform.
*
* @param at
* the specified AffineTransform object or null.
* @return PathIterator object for the Shape.
*/
public PathIterator getPathIterator(AffineTransform at);
/**
* Gets the PathIterator object of the Shape which provides access to the
* coordinates of the shapes boundary modified by the specified
* AffineTransform. The flatness parameter defines the amount of subdivision
* of the curved segments and specifies the maximum distance which every
* point on the unflattened transformed curve can deviate from the returned
* flattened path segments.
*
* @param at
* the specified AffineTransform object or null.
* @param flatness
* the maximum number of the control points for a given curve
* which varies from colinear before a subdivided curve is
* replaced by a straight line connecting the endpoints.
* @return PathIterator object for the Shape.
*/
public PathIterator getPathIterator(AffineTransform at, double flatness);
/**
* Checks whether or not the interior of rectangular specified by [x, y,
* width, height] parameters intersects the interior of the Shape.
*
* @param x
* the X double coordinate of the rectangle's upper left corner.
* @param y
* the Y double coordinate of the rectangle's upper left corner.
* @param w
* the width of rectangle.
* @param h
* the height of rectangle.
* @return true, if the rectangle specified by [x, y, width, height]
* parameters intersects the interior of the Shape, false otherwise.
*/
public boolean intersects(double x, double y, double w, double h);
/**
* Checks whether or not the interior of rectangle specified by Rectangle2D
* object intersects the interior of the Shape.
*
* @param r
* the Rectangle2D object.
* @return true, if the Rectangle2D intersects the interior of the Shape,
* otherwise false.
*/
public boolean intersects(Rectangle2D r);
}
+57
View File
@@ -0,0 +1,57 @@
package java.awt;
import java.awt.datatransfer.*;
import java.awt.peer.*;
import javax.imageio.*;
import java.io.*;
public class Toolkit extends Object
{
private static Toolkit toolkit = new Toolkit();
private DesktopPeer desktopPeer = new DesktopPeer(){};
private Clipboard clipboard = new Clipboard();
public Image createImage(String fileStr)
{
try {
return ImageIO.read(new File(fileStr));
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static void checkHeadless()
{
GraphicsEnvironment.checkHeadless();
}
public boolean isAlwaysOnTopSupported()
{
// Android implementation: NOT SUPPORTED
return false;
}
private class AWTTreeLock {
}
final Object awtTreeLock = new AWTTreeLock();
private Toolkit()
{}
public DesktopPeer createDesktopPeer()
{
return desktopPeer;
}
public static Toolkit getDefaultToolkit()
{
return toolkit;
}
public Clipboard getSystemClipboard() throws HeadlessException
{
return clipboard;
}
}
@@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Pavel Dolgov
* @version $Revision$
*/
package java.awt;
/**
* The Transparency interface defines transparency's general modes.
*
* @since Android 1.0
*/
public interface Transparency {
/**
* The Constant OPAQUE represents completely opaque data, all pixels have an
* alpha value of 1.0.
*/
public static final int OPAQUE = 1;
/**
* The Constant BITMASK represents data which can be either completely
* opaque, with an alpha value of 1.0, or completely transparent, with an
* alpha value of 0.0.
*/
public static final int BITMASK = 2;
/**
* The Constant TRANSLUCENT represents data which alpha value can vary
* between and including 0.0 and 1.0.
*/
public static final int TRANSLUCENT = 3;
/**
* Gets the transparency mode.
*
* @return the transparency mode: OPAQUE, BITMASK or TRANSLUCENT.
*/
public int getTransparency();
}
+88
View File
@@ -0,0 +1,88 @@
package java.awt;
import java.util.*;
import java.awt.peer.*;
import sun.security.util.*;
import java.awt.mod.*;
public class Window extends Container
{
private boolean alwaysOnTop;
private static List<Window> windows;
private String title = "Untitled";
static {
if (windows == null) {
windows = new ArrayList<Window>();
}
}
public static Window[] getWindows() {
return windows.toArray(new Window[0]);
}
public Window() {
this("");
}
public Window(String title) {
this.title = title;
// Don't add WindowManager
// if (!(this instanceof AndroidWindowManager)) {
windows.add(this);
// }
}
public void setTitle(String title){
this.title = title;
}
public String getTitle() {
return this.title;
}
public final void setAlwaysOnTop(boolean alwaysOnTop) throws SecurityException {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(SecurityConstants.AWT.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION);
}
boolean oldAlwaysOnTop;
synchronized(this) {
oldAlwaysOnTop = this.alwaysOnTop;
this.alwaysOnTop = alwaysOnTop;
}
if (oldAlwaysOnTop != alwaysOnTop ) {
if (isAlwaysOnTopSupported()) {
/*
WindowPeer peer = (WindowPeer)this.peer;
synchronized(getTreeLock()) {
if (peer != null) {
//peer.setAlwaysOnTop(alwaysOnTop);
}
}
*/
}
firePropertyChange("alwaysOnTop", oldAlwaysOnTop, alwaysOnTop);
}
}
public boolean isAlwaysOnTopSupported() {
return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported();
}
public final boolean isAlwaysOnTop() {
return alwaysOnTop;
}
public void pack() {
//super.pack();
}
public void setIconImages(List<Image> icons)
{
// TODO: Implement this method
}
}
@@ -0,0 +1,44 @@
package java.awt.datatransfer;
import android.app.Activity;
import android.content.Context;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.widget.Toast;
import net.kdt.pojavlaunch.Tools;
import java.awt.mod.*;
public class Clipboard extends Object
{
public synchronized void setContents(final Transferable contents, ClipboardOwner owner) {
try {
final Activity act = ModdingKit.getCurrentActivity();
act.runOnUiThread(new Runnable(){
@Override
public void run()
{
ClipboardManager clipboard = (ClipboardManager) act.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText("Copied text", ((StringSelection) contents).getString());
clipboard.setPrimaryClip(clip);
Toast.makeText(act, "Copied to clipboard!", Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized Transferable getContents(Object requestor) {
try {
final Activity act = ModdingKit.getCurrentActivity();
ClipboardManager clipboard = (ClipboardManager) act.getSystemService(Context.CLIPBOARD_SERVICE);
return new StringSelection(clipboard.getText().toString());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
@@ -0,0 +1,51 @@
/*
* Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt.datatransfer;
/**
* Defines the interface for classes that will provide data to
* a clipboard. An instance of this interface becomes the owner
* of the contents of a clipboard (clipboard owner) if it is
* passed as an argument to
* {@link java.awt.datatransfer.Clipboard#setContents} method of
* the clipboard and this method returns successfully.
* The instance remains the clipboard owner until another application
* or another object within this application asserts ownership
* of this clipboard.
*
* @see java.awt.datatransfer.Clipboard
*
* @author Amy Fowler
*/
public interface ClipboardOwner {
/**
* Notifies this object that it is no longer the clipboard owner.
* This method will be called when another application or another
* object within this application asserts ownership of the clipboard.
*
* @param clipboard the clipboard that is no longer owned
* @param contents the contents which this owner had placed on the clipboard
*/
public void lostOwnership(Clipboard clipboard, Transferable contents);
}
@@ -0,0 +1,719 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Michael Danilov
* @version $Revision$
*/
package java.awt.datatransfer;
import java.io.*;
import java.nio.*;
import java.nio.charset.*;
import java.util.*;
import org.apache.harmony.awt.internal.nls.Messages;
public class DataFlavor implements Externalizable, Cloneable {
private static final long serialVersionUID = 8367026044764648243L;
/**
* @deprecated
*/
@Deprecated
public static final DataFlavor plainTextFlavor =
new DataFlavor("text/plain; charset=unicode; class=java.io.InputStream", //$NON-NLS-1$
"Plain Text"); //$NON-NLS-1$
public static final DataFlavor stringFlavor =
new DataFlavor("application/x-java-serialized-object; class=java.lang.String", //$NON-NLS-1$
"Unicode String"); //$NON-NLS-1$
/* public static final DataFlavor imageFlavor =
new DataFlavor("image/x-java-image; class=java.awt.Image", //$NON-NLS-1$
"Image"); //$NON-NLS-1$
*/
public static final DataFlavor javaFileListFlavor =
new DataFlavor("application/x-java-file-list; class=java.util.List", //$NON-NLS-1$
"application/x-java-file-list"); //$NON-NLS-1$
public static final String javaJVMLocalObjectMimeType =
"application/x-java-jvm-local-objectref"; //$NON-NLS-1$
public static final String javaRemoteObjectMimeType =
"application/x-java-remote-object"; //$NON-NLS-1$
public static final String javaSerializedObjectMimeType =
"application/x-java-serialized-object"; //$NON-NLS-1$
private static final String sortedTextFlavors[] = {
"text/sgml", //$NON-NLS-1$
"text/xml", //$NON-NLS-1$
"text/html", //$NON-NLS-1$
"text/rtf", //$NON-NLS-1$
"text/enriched", //$NON-NLS-1$
"text/richtext", //$NON-NLS-1$
"text/uri-list", //$NON-NLS-1$
"text/tab-separated-values", //$NON-NLS-1$
"text/t140" , //$NON-NLS-1$
"text/rfc822-headers", //$NON-NLS-1$
"text/parityfec", //$NON-NLS-1$
"text/directory", //$NON-NLS-1$
"text/css", //$NON-NLS-1$
"text/calendar", //$NON-NLS-1$
"application/x-java-serialized-object", //$NON-NLS-1$
"text/plain" //$NON-NLS-1$
};
private static DataFlavor plainUnicodeFlavor = null;
private String humanPresentableName;
private Class<?> representationClass;
private MimeTypeProcessor.MimeType mimeInfo;
public static final DataFlavor getTextPlainUnicodeFlavor() {
if (plainUnicodeFlavor == null) {
plainUnicodeFlavor = new DataFlavor("text/plain" //$NON-NLS-1$
+ "; charset=unicode"// + DTK.getDTK().getDefaultCharset() //$NON-NLS-1$
+ "; class=java.io.InputStream", //$NON-NLS-1$
"Plain Text"); //$NON-NLS-1$
}
return plainUnicodeFlavor;
}
protected static final Class<?> tryToLoadClass(String className, ClassLoader fallback)
throws ClassNotFoundException
{
try {
return Class.forName(className);
} catch (ClassNotFoundException e0) {
try {
return ClassLoader.getSystemClassLoader().loadClass(className);
} catch (ClassNotFoundException e1) {
ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
if (contextLoader != null) {
try {
return contextLoader.loadClass(className);
} catch (ClassNotFoundException e2) {
}
}
return fallback.loadClass(className);
}
}
}
private static boolean isCharsetSupported(String charset) {
try {
return Charset.isSupported(charset);
} catch (IllegalCharsetNameException e) {
return false;
}
}
public DataFlavor() {
mimeInfo = null;
humanPresentableName = null;
representationClass = null;
}
public DataFlavor(Class<?> representationClass, String humanPresentableName) {
mimeInfo = new MimeTypeProcessor.MimeType("application", "x-java-serialized-object"); //$NON-NLS-1$ //$NON-NLS-2$
if (humanPresentableName != null) {
this.humanPresentableName = humanPresentableName;
} else {
this.humanPresentableName = "application/x-java-serialized-object"; //$NON-NLS-1$
}
mimeInfo.addParameter("class", representationClass.getName()); //$NON-NLS-1$
this.representationClass = representationClass;
}
public DataFlavor(String mimeType, String humanPresentableName) {
try {
init(mimeType, humanPresentableName, null);
} catch (ClassNotFoundException e) {
// awt.16C=Can't load class: {0}
throw new IllegalArgumentException(Messages.getString("awt.16C", mimeInfo.getParameter("class")),e); //$NON-NLS-1$//$NON-NLS-2$
}
}
public DataFlavor(String mimeType) throws ClassNotFoundException {
init(mimeType, null, null);
}
public DataFlavor(String mimeType, String humanPresentableName, ClassLoader classLoader)
throws ClassNotFoundException
{
init(mimeType, humanPresentableName, classLoader);
}
private void init(String mimeType, String humanPresentableName, ClassLoader classLoader)
throws ClassNotFoundException
{
String className;
try {
mimeInfo = MimeTypeProcessor.parse(mimeType);
} catch (IllegalArgumentException e) {
// awt.16D=Can't parse MIME type: {0}
throw new IllegalArgumentException(Messages.getString("awt.16D", mimeType)); //$NON-NLS-1$
}
if (humanPresentableName != null) {
this.humanPresentableName = humanPresentableName;
} else {
this.humanPresentableName = mimeInfo.getPrimaryType() + '/' + mimeInfo.getSubType();
}
className = mimeInfo.getParameter("class"); //$NON-NLS-1$
if (className == null) {
className = "java.io.InputStream"; //$NON-NLS-1$
mimeInfo.addParameter("class", className); //$NON-NLS-1$
}
representationClass = (classLoader == null) ?
Class.forName(className) :
classLoader.loadClass(className);
}
private String getCharset() {
if ((mimeInfo == null) || isCharsetRedundant()) {
return ""; //$NON-NLS-1$
}
String charset = mimeInfo.getParameter("charset"); //$NON-NLS-1$
if (isCharsetRequired() && ((charset == null) || (charset.length() == 0))) {
return "unicode";
}
if (charset == null) {
return ""; //$NON-NLS-1$
}
return charset;
}
private boolean isCharsetRequired() {
String type = mimeInfo.getFullType();
return (type.equals("text/sgml") || //$NON-NLS-1$
type.equals("text/xml") || //$NON-NLS-1$
type.equals("text/html") || //$NON-NLS-1$
type.equals("text/enriched") || //$NON-NLS-1$
type.equals("text/richtext") || //$NON-NLS-1$
type.equals("text/uri-list") || //$NON-NLS-1$
type.equals("text/directory") || //$NON-NLS-1$
type.equals("text/css") || //$NON-NLS-1$
type.equals("text/calendar") || //$NON-NLS-1$
type.equals("application/x-java-serialized-object") || //$NON-NLS-1$
type.equals("text/plain")); //$NON-NLS-1$
}
private boolean isCharsetRedundant() {
String type = mimeInfo.getFullType();
return (type.equals("text/rtf") || //$NON-NLS-1$
type.equals("text/tab-separated-values") || //$NON-NLS-1$
type.equals("text/t140") || //$NON-NLS-1$
type.equals("text/rfc822-headers") || //$NON-NLS-1$
type.equals("text/parityfec")); //$NON-NLS-1$
}
MimeTypeProcessor.MimeType getMimeInfo() {
return mimeInfo;
}
public String getPrimaryType() {
return (mimeInfo != null) ? mimeInfo.getPrimaryType() : null;
}
public String getSubType() {
return (mimeInfo != null) ? mimeInfo.getSubType() : null;
}
public String getMimeType() {
return (mimeInfo != null) ? MimeTypeProcessor.assemble(mimeInfo) : null;
}
public String getParameter(String paramName) {
String lowerName = paramName.toLowerCase();
if (lowerName.equals("humanpresentablename")) { //$NON-NLS-1$
return humanPresentableName;
}
return mimeInfo != null ? mimeInfo.getParameter(lowerName) : null;
}
public String getHumanPresentableName() {
return humanPresentableName;
}
public void setHumanPresentableName(String humanPresentableName) {
this.humanPresentableName = humanPresentableName;
}
public Class<?> getRepresentationClass() {
return representationClass;
}
public final Class<?> getDefaultRepresentationClass() {
return InputStream.class;
}
public final String getDefaultRepresentationClassAsString() {
return getDefaultRepresentationClass().getName();
}
public boolean isRepresentationClassSerializable() {
return Serializable.class.isAssignableFrom(representationClass);
}
public boolean isRepresentationClassRemote() {
// Code should be enabled when RMI is supported
// return java.rmi.Remote.class.isAssignableFrom(representationClass);
return false;
}
public boolean isRepresentationClassReader() {
return Reader.class.isAssignableFrom(representationClass);
}
public boolean isRepresentationClassInputStream() {
return InputStream.class.isAssignableFrom(representationClass);
}
public boolean isRepresentationClassCharBuffer() {
return CharBuffer.class.isAssignableFrom(representationClass);
}
public boolean isRepresentationClassByteBuffer() {
return ByteBuffer.class.isAssignableFrom(representationClass);
}
/**
* @deprecated
*/
@Deprecated
protected String normalizeMimeTypeParameter(String parameterName, String parameterValue) {
return parameterValue;
}
/**
* @deprecated
*/
@Deprecated
protected String normalizeMimeType(String mimeType) {
return mimeType;
}
public final boolean isMimeTypeEqual(DataFlavor dataFlavor) {
return mimeInfo != null ? mimeInfo.equals(dataFlavor.mimeInfo)
: (dataFlavor.mimeInfo == null);
}
public boolean isMimeTypeEqual(String mimeType) {
try {
return mimeInfo.equals(MimeTypeProcessor.parse(mimeType));
} catch (IllegalArgumentException e) {
return false;
}
}
public synchronized void writeExternal(ObjectOutput os) throws IOException {
os.writeObject(humanPresentableName);
os.writeObject(mimeInfo);
}
public synchronized void readExternal(ObjectInput is)
throws IOException, ClassNotFoundException
{
humanPresentableName = (String) is.readObject();
mimeInfo = (MimeTypeProcessor.MimeType) is.readObject();
representationClass = (mimeInfo != null) ?
Class.forName(mimeInfo.getParameter("class")) : null; //$NON-NLS-1$
}
@Override
public Object clone() throws CloneNotSupportedException {
DataFlavor clone = new DataFlavor();
clone.humanPresentableName = humanPresentableName;
clone.representationClass = representationClass;
clone.mimeInfo = (mimeInfo != null) ? (MimeTypeProcessor.MimeType)
mimeInfo.clone() : null;
return clone;
}
@Override
public String toString() {
/* The format is based on 1.5 release behavior
* which can be revealed by the following code:
*
* System.out.println(DataFlavor.imageFlavor.toString());
*/
return (getClass().getName()
+ "[MimeType=(" + getMimeType() //$NON-NLS-1$
+ ");humanPresentableName=" + humanPresentableName + "]"); //$NON-NLS-1$ //$NON-NLS-2$
}
public boolean isMimeTypeSerializedObject() {
return isMimeTypeEqual(javaSerializedObjectMimeType);
}
@Override
public boolean equals(Object o) {
if ((o == null) || !(o instanceof DataFlavor)) {
return false;
}
return equals((DataFlavor) o);
}
public boolean equals(DataFlavor that) {
if (that == this) {
return true;
}
if (that == null) {
return false;
}
if (mimeInfo == null) {
return (that.mimeInfo == null);
}
if (!(mimeInfo.equals(that.mimeInfo) &&
representationClass.equals(that.representationClass)))
{
return false;
}
if (!mimeInfo.getPrimaryType().equals("text") || isUnicodeFlavor()) { //$NON-NLS-1$
return true;
}
String charset1 = getCharset();
String charset2 = that.getCharset();
if (!isCharsetSupported(charset1) || !isCharsetSupported(charset2)) {
return charset1.equalsIgnoreCase(charset2);
}
return (Charset.forName(charset1).equals(Charset.forName(charset2)));
}
@Deprecated
public boolean equals(String s) {
if (s == null) {
return false;
}
return isMimeTypeEqual(s);
}
public boolean match(DataFlavor that) {
return equals(that);
}
@Override
public int hashCode() {
return getKeyInfo().hashCode();
}
private String getKeyInfo() {
String key = mimeInfo.getFullType() + ";class=" + representationClass.getName(); //$NON-NLS-1$
if (!mimeInfo.getPrimaryType().equals("text") || isUnicodeFlavor()) { //$NON-NLS-1$
return key;
}
return key + ";charset=" + getCharset().toLowerCase(); //$NON-NLS-1$
}
public boolean isFlavorSerializedObjectType() {
return (isMimeTypeSerializedObject()
&& isRepresentationClassSerializable());
}
public boolean isFlavorRemoteObjectType() {
return (isMimeTypeEqual(javaRemoteObjectMimeType)
&& isRepresentationClassRemote());
}
public boolean isFlavorJavaFileListType() {
return (java.util.List.class.isAssignableFrom(representationClass) &&
isMimeTypeEqual(javaFileListFlavor));
}
public boolean isFlavorTextType() {
if (equals(stringFlavor) || equals(plainTextFlavor)) {
return true;
}
if ((mimeInfo != null) && !mimeInfo.getPrimaryType().equals("text")) { //$NON-NLS-1$
return false;
}
String charset = getCharset();
if (isByteCodeFlavor()) {
if (charset.length() != 0) {
return isCharsetSupported(charset);
}
return true;
}
return isUnicodeFlavor();
}
public Reader getReaderForText(Transferable transferable)
throws UnsupportedFlavorException, IOException
{
Object data = transferable.getTransferData(this);
if (data == null) {
// awt.16E=Transferable has null data
throw new IllegalArgumentException(Messages.getString("awt.16E")); //$NON-NLS-1$
}
if (data instanceof Reader) {
Reader reader = (Reader) data;
reader.reset();
return reader;
} else if (data instanceof String) {
return new StringReader((String) data);
} else if (data instanceof CharBuffer) {
return new CharArrayReader(((CharBuffer) data).array());
} else if (data instanceof char[]) {
return new CharArrayReader((char[]) data);
} else {
String charset = getCharset();
InputStream stream;
if (data instanceof InputStream) {
stream = (InputStream) data;
stream.reset();
} else if (data instanceof ByteBuffer) {
stream = new ByteArrayInputStream((((ByteBuffer) data).array()));
} else if (data instanceof byte[]) {
stream = new ByteArrayInputStream((byte[]) data);
} else {
// awt.16F=Can't create reader for this representation class
throw new IllegalArgumentException(Messages.getString("awt.16F")); //$NON-NLS-1$
}
if (charset.length() == 0) {
return new InputStreamReader(stream);
}
return new InputStreamReader(stream, charset);
}
}
public static final DataFlavor selectBestTextFlavor(DataFlavor[] availableFlavors) {
if (availableFlavors == null) {
return null;
}
List<List<DataFlavor>> sorted = sortTextFlavorsByType(new LinkedList<DataFlavor>(Arrays.asList(availableFlavors)));
if (sorted.isEmpty()) {
return null;
}
List<DataFlavor> bestSorted = sorted.get(0);
if (bestSorted.size() == 1) {
return bestSorted.get(0);
}
if (bestSorted.get(0).getCharset().length() == 0) {
return selectBestFlavorWOCharset(bestSorted);
}
return selectBestFlavorWCharset(bestSorted);
}
private static DataFlavor selectBestFlavorWCharset(List<DataFlavor> list) {
List<DataFlavor> best;
best = getFlavors(list, Reader.class);
if (best != null) {
return best.get(0);
}
best = getFlavors(list, String.class);
if (best != null) {
return best.get(0);
}
best = getFlavors(list, CharBuffer.class);
if (best != null) {
return best.get(0);
}
best = getFlavors(list, char[].class);
if (best != null) {
return best.get(0);
}
return selectBestByCharset(list);
}
private static DataFlavor selectBestByCharset(List<DataFlavor> list) {
List<DataFlavor> best;
best = getFlavors(list, new String[] {"UTF-16", "UTF-8", "UTF-16BE", "UTF-16LE"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
if (best == null) {
best = getFlavors(list, new String[] {"unicode"});
if (best == null) {
best = getFlavors(list, new String[] {"US-ASCII"}); //$NON-NLS-1$
if (best == null) {
best = selectBestByAlphabet(list);
}
}
}
if (best != null) {
if (best.size() == 1) {
return best.get(0);
}
return selectBestFlavorWOCharset(best);
}
return null;
}
private static List<DataFlavor> selectBestByAlphabet(List<DataFlavor> list) {
String charsets[] = new String[list.size()];
LinkedList<DataFlavor> best = new LinkedList<DataFlavor>();
for (int i = 0; i < charsets.length; i++) {
charsets[i] = list.get(i).getCharset();
}
Arrays.sort(charsets, String.CASE_INSENSITIVE_ORDER);
for (DataFlavor flavor : list) {
if (charsets[0].equalsIgnoreCase(flavor.getCharset())) {
best.add(flavor);
}
}
return best.isEmpty() ? null : best;
}
private static List<DataFlavor> getFlavors(List<DataFlavor> list, String[] charset) {
LinkedList<DataFlavor> sublist = new LinkedList<DataFlavor>();
for (Iterator<DataFlavor> i = list.iterator(); i.hasNext();) {
DataFlavor flavor = i.next();
if (isCharsetSupported(flavor.getCharset())) {
for (String element : charset) {
if (Charset.forName(element).equals(Charset.forName(flavor.getCharset()))) {
sublist.add(flavor);
}
}
} else {
i.remove();
}
}
return sublist.isEmpty() ? null : list;
}
private static DataFlavor selectBestFlavorWOCharset(List<DataFlavor> list) {
List<DataFlavor> best;
best = getFlavors(list, InputStream.class);
if (best != null) {
return best.get(0);
}
best = getFlavors(list, ByteBuffer.class);
if (best != null) {
return best.get(0);
}
best = getFlavors(list, byte[].class);
if (best != null) {
return best.get(0);
}
return list.get(0);
}
private static List<DataFlavor> getFlavors(List<DataFlavor> list, Class<?> klass) {
LinkedList<DataFlavor> sublist = new LinkedList<DataFlavor>();
for (DataFlavor flavor : list) {
if (flavor.representationClass.equals(klass)) {
sublist.add(flavor);
}
}
return sublist.isEmpty() ? null : list;
}
private static List<List<DataFlavor>> sortTextFlavorsByType(List<DataFlavor> availableFlavors) {
LinkedList<List<DataFlavor>> list = new LinkedList<List<DataFlavor>>();
for (String element : sortedTextFlavors) {
List<DataFlavor> subList = fetchTextFlavors(availableFlavors, element);
if (subList != null) {
list.addLast(subList);
}
}
if (!availableFlavors.isEmpty()) {
list.addLast(availableFlavors);
}
return list;
}
private static List<DataFlavor> fetchTextFlavors(List<DataFlavor> availableFlavors, String mimeType) {
LinkedList<DataFlavor> list = new LinkedList<DataFlavor>();
for (Iterator<DataFlavor> i = availableFlavors.iterator(); i.hasNext();) {
DataFlavor flavor = i.next();
if (flavor.isFlavorTextType()) {
if (flavor.mimeInfo.getFullType().equals(mimeType)) {
if (!list.contains(flavor)) {
list.add(flavor);
}
i.remove();
}
} else {
i.remove();
}
}
return list.isEmpty() ? null : list;
}
private boolean isUnicodeFlavor() {
return (representationClass != null)
&& (representationClass.equals(Reader.class)
|| representationClass.equals(String.class)
|| representationClass.equals(CharBuffer.class)
|| representationClass.equals(char[].class));
}
private boolean isByteCodeFlavor() {
return (representationClass != null)
&& (representationClass.equals(InputStream.class)
|| representationClass.equals(ByteBuffer.class)
|| representationClass.equals(byte[].class));
}
}
@@ -0,0 +1,262 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.awt.datatransfer;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;
final class MimeTypeProcessor {
private static MimeTypeProcessor instance;
private MimeTypeProcessor() {
super();
}
static MimeType parse(String str) {
MimeType res;
if (instance == null) {
instance = new MimeTypeProcessor();
}
res = new MimeType();
if (str != null) {
StringPosition pos = new StringPosition();
retrieveType(str, res, pos);
retrieveParams(str, res, pos);
}
return res;
}
static String assemble(MimeType type) {
StringBuilder buf = new StringBuilder();
buf.append(type.getFullType());
for (Enumeration<String> keys = type.parameters.keys(); keys.hasMoreElements();) {
String name = keys.nextElement();
String value = type.parameters.get(name);
buf.append("; "); //$NON-NLS-1$
buf.append(name);
buf.append("=\""); //$NON-NLS-1$
buf.append(value);
buf.append('"');
}
return buf.toString();
}
private static void retrieveType(String str, MimeType res, StringPosition pos) {
res.primaryType = retrieveToken(str, pos).toLowerCase();
pos.i = getNextMeaningfulIndex(str, pos.i);
if ((pos.i >= str.length()) || (str.charAt(pos.i) != '/')) {
throw new IllegalArgumentException();
}
pos.i++;
res.subType = retrieveToken(str, pos).toLowerCase();
}
private static void retrieveParams(String str, MimeType res, StringPosition pos) {
res.parameters = new Hashtable<String, String>();
res.systemParameters = new Hashtable<String, Object>();
do {
pos.i = getNextMeaningfulIndex(str, pos.i);
if (pos.i >= str.length()) {
return;
}
if (str.charAt(pos.i) != ';') {
throw new IllegalArgumentException();
}
pos.i++;
retrieveParam(str, res, pos);
} while (true);
}
private static void retrieveParam(String str, MimeType res, StringPosition pos) {
String name = retrieveToken(str, pos).toLowerCase();
pos.i = getNextMeaningfulIndex(str, pos.i);
if ((pos.i >= str.length()) || (str.charAt(pos.i) != '=')) {
throw new IllegalArgumentException();
}
pos.i++;
pos.i = getNextMeaningfulIndex(str, pos.i);
if ((pos.i >= str.length())) {
throw new IllegalArgumentException();
}
String value;
if (str.charAt(pos.i) == '"') {
value = retrieveQuoted(str, pos);
} else {
value = retrieveToken(str, pos);
}
res.parameters.put(name, value);
}
private static String retrieveQuoted(String str, StringPosition pos) {
StringBuilder buf = new StringBuilder();
boolean check = true;
pos.i++;
while ((str.charAt(pos.i) != '"') || !check) {
char c = str.charAt(pos.i++);
if (!check) {
check = true;
} else if (c == '\\') {
check = false;
}
if (check) {
buf.append(c);
}
if (pos.i == str.length()) {
throw new IllegalArgumentException();
}
}
pos.i++;
return buf.toString();
}
private static String retrieveToken(String str, StringPosition pos) {
StringBuilder buf = new StringBuilder();
pos.i = getNextMeaningfulIndex(str, pos.i);
if ((pos.i >= str.length()) || isTSpecialChar(str.charAt(pos.i))) {
throw new IllegalArgumentException();
}
do {
buf.append(str.charAt(pos.i++));
} while ((pos.i < str.length())
&& isMeaningfulChar(str.charAt(pos.i))
&& !isTSpecialChar(str.charAt(pos.i)));
return buf.toString();
}
private static int getNextMeaningfulIndex(String str, int i) {
while ((i < str.length()) && !isMeaningfulChar(str.charAt(i))) {
i++;
}
return i;
}
private static boolean isTSpecialChar(char c) {
return ((c == '(') || (c == ')') || (c == '[') || (c == ']') || (c == '<')
|| (c == '>') || (c == '@') || (c == ',') || (c == ';') || (c == ':')
|| (c == '\\') || (c == '\"') || (c == '/') || (c == '?') || (c == '='));
}
private static boolean isMeaningfulChar(char c) {
return ((c >= '!') && (c <= '~'));
}
private static final class StringPosition {
int i = 0;
}
static final class MimeType implements Cloneable, Serializable {
private static final long serialVersionUID = -6693571907475992044L;
private String primaryType;
private String subType;
private Hashtable<String, String> parameters;
private Hashtable<String, Object> systemParameters;
MimeType() {
primaryType = null;
subType = null;
parameters = null;
systemParameters = null;
}
MimeType(String primaryType, String subType) {
this.primaryType = primaryType;
this.subType = subType;
parameters = new Hashtable<String, String>();
systemParameters = new Hashtable<String, Object>();
}
boolean equals(MimeType that) {
if (that == null) {
return false;
}
return getFullType().equals(that.getFullType());
}
String getPrimaryType() {
return primaryType;
}
String getSubType() {
return subType;
}
String getFullType() {
return (primaryType + "/" + subType); //$NON-NLS-1$
}
String getParameter(String name) {
return parameters.get(name);
}
void addParameter(String name, String value) {
if (value == null) {
return;
}
if ((value.charAt(0) == '\"')
&& (value.charAt(value.length() - 1) == '\"')) {
value = value.substring(1, value.length() - 2);
}
if (value.length() == 0) {
return;
}
parameters.put(name, value);
}
void removeParameter(String name) {
parameters.remove(name);
}
Object getSystemParameter(String name) {
return systemParameters.get(name);
}
void addSystemParameter(String name, Object value) {
systemParameters.put(name, value);
}
@SuppressWarnings("unchecked")
@Override
public Object clone() {
MimeType clone = new MimeType(primaryType, subType);
clone.parameters = (Hashtable<String, String>)parameters.clone();
clone.systemParameters = (Hashtable<String, Object>)systemParameters.clone();
return clone;
}
}
}
@@ -0,0 +1,38 @@
package java.awt.datatransfer;
import java.io.IOException;
public class StringSelection implements Transferable
{
@Override
public DataFlavor[] getTransferDataFlavors()
{
// TODO: Implement this method
return null;
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor)
{
// TODO: Implement this method
return false;
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException
{
// TODO: Implement this method
return null;
}
private String data;
public StringSelection(String data)
{
this.data = data;
}
public String getString()
{
return data;
}
}
@@ -0,0 +1,65 @@
/*
* Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt.datatransfer;
import java.io.IOException;
/**
* Defines the interface for classes that can be used to provide data
* for a transfer operation.
* <p>
* For information on using data transfer with Swing, see
* <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html">
* How to Use Drag and Drop and Data Transfer</a>,
* a section in <em>The Java Tutorial</em>, for more information.
*
* @author Amy Fowler
*/
public interface Transferable {
/**
* Returns an array of DataFlavor objects indicating the flavors the data
* can be provided in. The array should be ordered according to preference
* for providing the data (from most richly descriptive to least descriptive).
* @return an array of data flavors in which this data can be transferred
*/
public DataFlavor[] getTransferDataFlavors();
/**
* Returns whether or not the specified data flavor is supported for
* this object.
* @param flavor the requested flavor for the data
* @return boolean indicating whether or not the data flavor is supported
*/
public boolean isDataFlavorSupported(DataFlavor flavor);
/**
* Returns an object which represents the data to be transferred. The class
* of the object returned is defined by the representation class of the flavor.
*
* @param flavor the requested flavor for the data
* @see DataFlavor#getRepresentationClass
* @exception IOException if the data is no longer available
* in the requested flavor.
* @exception UnsupportedFlavorException if the requested data flavor is
* not supported.
*/
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException;
}
@@ -0,0 +1,26 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.awt.datatransfer;
public class UnsupportedFlavorException extends Exception {
private static final long serialVersionUID = 5383814944251665601L;
public UnsupportedFlavorException(DataFlavor flavor) {
super("flavor = " + String.valueOf(flavor)); //$NON-NLS-1$
}
}
@@ -0,0 +1,5 @@
package java.awt.event;
public class WindowAdapter implements WindowListener
{
}
@@ -0,0 +1,431 @@
/*
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.awt.event;
import java.awt.Window;
import java.lang.annotation.Native;
/**
* A low-level event that indicates that a window has changed its status. This
* low-level event is generated by a Window object when it is opened, closed,
* activated, deactivated, iconified, or deiconified, or when focus is
* transfered into or out of the Window.
* <P>
* The event is passed to every <code>WindowListener</code>
* or <code>WindowAdapter</code> object which registered to receive such
* events using the window's <code>addWindowListener</code> method.
* (<code>WindowAdapter</code> objects implement the
* <code>WindowListener</code> interface.) Each such listener object
* gets this <code>WindowEvent</code> when the event occurs.
* <p>
* An unspecified behavior will be caused if the {@code id} parameter
* of any particular {@code WindowEvent} instance is not
* in the range from {@code WINDOW_FIRST} to {@code WINDOW_LAST}.
*
* @author Carl Quinn
* @author Amy Fowler
*
* @see WindowAdapter
* @see WindowListener
* @see <a href="https://docs.oracle.com/javase/tutorial/uiswing/events/windowlistener.html">Tutorial: Writing a Window Listener</a>
*
* @since JDK1.1
*/
public class WindowEvent /* extends ComponentEvent */ {
/**
* The first number in the range of ids used for window events.
*/
public static final int WINDOW_FIRST = 200;
/**
* The window opened event. This event is delivered only
* the first time a window is made visible.
*/
@Native public static final int WINDOW_OPENED = WINDOW_FIRST; // 200
/**
* The "window is closing" event. This event is delivered when
* the user attempts to close the window from the window's system menu.
* If the program does not explicitly hide or dispose the window
* while processing this event, the window close operation will be
* cancelled.
*/
@Native public static final int WINDOW_CLOSING = 1 + WINDOW_FIRST; //Event.WINDOW_DESTROY
/**
* The window closed event. This event is delivered after the displayable
* window has been closed as the result of a call to dispose.
* @see java.awt.Component#isDisplayable
* @see Window#dispose
*/
@Native public static final int WINDOW_CLOSED = 2 + WINDOW_FIRST;
/**
* The window iconified event. This event is delivered when
* the window has been changed from a normal to a minimized state.
* For many platforms, a minimized window is displayed as
* the icon specified in the window's iconImage property.
* @see java.awt.Frame#setIconImage
*/
@Native public static final int WINDOW_ICONIFIED = 3 + WINDOW_FIRST; //Event.WINDOW_ICONIFY
/**
* The window deiconified event type. This event is delivered when
* the window has been changed from a minimized to a normal state.
*/
@Native public static final int WINDOW_DEICONIFIED = 4 + WINDOW_FIRST; //Event.WINDOW_DEICONIFY
/**
* The window-activated event type. This event is delivered when the Window
* becomes the active Window. Only a Frame or a Dialog can be the active
* Window. The native windowing system may denote the active Window or its
* children with special decorations, such as a highlighted title bar. The
* active Window is always either the focused Window, or the first Frame or
* Dialog that is an owner of the focused Window.
*/
@Native public static final int WINDOW_ACTIVATED = 5 + WINDOW_FIRST;
/**
* The window-deactivated event type. This event is delivered when the
* Window is no longer the active Window. Only a Frame or a Dialog can be
* the active Window. The native windowing system may denote the active
* Window or its children with special decorations, such as a highlighted
* title bar. The active Window is always either the focused Window, or the
* first Frame or Dialog that is an owner of the focused Window.
*/
@Native public static final int WINDOW_DEACTIVATED = 6 + WINDOW_FIRST;
/**
* The window-gained-focus event type. This event is delivered when the
* Window becomes the focused Window, which means that the Window, or one
* of its subcomponents, will receive keyboard events.
*/
@Native public static final int WINDOW_GAINED_FOCUS = 7 + WINDOW_FIRST;
/**
* The window-lost-focus event type. This event is delivered when a Window
* is no longer the focused Window, which means keyboard events will no
* longer be delivered to the Window or any of its subcomponents.
*/
@Native public static final int WINDOW_LOST_FOCUS = 8 + WINDOW_FIRST;
/**
* The window-state-changed event type. This event is delivered
* when a Window's state is changed by virtue of it being
* iconified, maximized etc.
* @since 1.4
*/
@Native public static final int WINDOW_STATE_CHANGED = 9 + WINDOW_FIRST;
/**
* The last number in the range of ids used for window events.
*/
public static final int WINDOW_LAST = WINDOW_STATE_CHANGED;
/**
* The other Window involved in this focus or activation change. For a
* WINDOW_ACTIVATED or WINDOW_GAINED_FOCUS event, this is the Window that
* lost activation or focus. For a WINDOW_DEACTIVATED or WINDOW_LOST_FOCUS
* event, this is the Window that gained activation or focus. For any other
* type of WindowEvent, or if the focus or activation change occurs with a
* native application, a Java application in a different VM, or with no
* other Window, null is returned.
*
* @see #getOppositeWindow
* @since 1.4
*/
transient Window opposite;
/**
* TBS
*/
int oldState;
int newState;
/*
* JDK 1.1 serialVersionUID
*/
private static final long serialVersionUID = -1567959133147912127L;
/**
* Constructs a <code>WindowEvent</code> object.
* <p>This method throws an
* <code>IllegalArgumentException</code> if <code>source</code>
* is <code>null</code>.
*
* @param source The <code>Window</code> object
* that originated the event
* @param id An integer indicating the type of event.
* For information on allowable values, see
* the class description for {@link WindowEvent}
* @param opposite The other window involved in the focus or activation
* change, or <code>null</code>
* @param oldState Previous state of the window for window state change event.
* See {@code #getOldState()} for allowable values
* @param newState New state of the window for window state change event.
* See {@code #getNewState()} for allowable values
* @throws IllegalArgumentException if <code>source</code> is null
* @see #getWindow()
* @see #getID()
* @see #getOppositeWindow()
* @see #getOldState()
* @see #getNewState()
* @since 1.4
*/
public WindowEvent(Window source, int id, Window opposite,
int oldState, int newState)
{
// super(source, id);
this.opposite = opposite;
this.oldState = oldState;
this.newState = newState;
}
/**
* Constructs a <code>WindowEvent</code> object with the
* specified opposite <code>Window</code>. The opposite
* <code>Window</code> is the other <code>Window</code>
* involved in this focus or activation change.
* For a <code>WINDOW_ACTIVATED</code> or
* <code>WINDOW_GAINED_FOCUS</code> event, this is the
* <code>Window</code> that lost activation or focus.
* For a <code>WINDOW_DEACTIVATED</code> or
* <code>WINDOW_LOST_FOCUS</code> event, this is the
* <code>Window</code> that gained activation or focus.
* If this focus change occurs with a native application, with a
* Java application in a different VM, or with no other
* <code>Window</code>, then the opposite Window is <code>null</code>.
* <p>This method throws an
* <code>IllegalArgumentException</code> if <code>source</code>
* is <code>null</code>.
*
* @param source The <code>Window</code> object that
* originated the event
* @param id An integer indicating the type of event.
* For information on allowable values, see
* the class description for {@link WindowEvent}.
* It is expected that this constructor will not
* be used for other then
* {@code WINDOW_ACTIVATED},{@code WINDOW_DEACTIVATED},
* {@code WINDOW_GAINED_FOCUS}, or {@code WINDOW_LOST_FOCUS}.
* {@code WindowEvent} types,
* because the opposite <code>Window</code> of other event types
* will always be {@code null}.
* @param opposite The other <code>Window</code> involved in the
* focus or activation change, or <code>null</code>
* @throws IllegalArgumentException if <code>source</code> is null
* @see #getWindow()
* @see #getID()
* @see #getOppositeWindow()
* @since 1.4
*/
public WindowEvent(Window source, int id, Window opposite) {
this(source, id, opposite, 0, 0);
}
/**
* Constructs a <code>WindowEvent</code> object with the specified
* previous and new window states.
* <p>This method throws an
* <code>IllegalArgumentException</code> if <code>source</code>
* is <code>null</code>.
*
* @param source The <code>Window</code> object
* that originated the event
* @param id An integer indicating the type of event.
* For information on allowable values, see
* the class description for {@link WindowEvent}.
* It is expected that this constructor will not
* be used for other then
* {@code WINDOW_STATE_CHANGED}
* {@code WindowEvent}
* types, because the previous and new window
* states are meaningless for other event types.
* @param oldState An integer representing the previous window state.
* See {@code #getOldState()} for allowable values
* @param newState An integer representing the new window state.
* See {@code #getNewState()} for allowable values
* @throws IllegalArgumentException if <code>source</code> is null
* @see #getWindow()
* @see #getID()
* @see #getOldState()
* @see #getNewState()
* @since 1.4
*/
public WindowEvent(Window source, int id, int oldState, int newState) {
this(source, id, null, oldState, newState);
}
/**
* Constructs a <code>WindowEvent</code> object.
* <p>This method throws an
* <code>IllegalArgumentException</code> if <code>source</code>
* is <code>null</code>.
*
* @param source The <code>Window</code> object that originated the event
* @param id An integer indicating the type of event.
* For information on allowable values, see
* the class description for {@link WindowEvent}.
* @throws IllegalArgumentException if <code>source</code> is null
* @see #getWindow()
* @see #getID()
*/
public WindowEvent(Window source, int id) {
this(source, id, null, 0, 0);
}
/**
* Returns the originator of the event.
*
* @return the Window object that originated the event
*/
public Window getWindow() {
return null; // (source instanceof Window) ? (Window)source : null;
}
/**
* Returns the other Window involved in this focus or activation change.
* For a WINDOW_ACTIVATED or WINDOW_GAINED_FOCUS event, this is the Window
* that lost activation or focus. For a WINDOW_DEACTIVATED or
* WINDOW_LOST_FOCUS event, this is the Window that gained activation or
* focus. For any other type of WindowEvent, or if the focus or activation
* change occurs with a native application, with a Java application in a
* different VM or context, or with no other Window, null is returned.
*
* @return the other Window involved in the focus or activation change, or
* null
* @since 1.4
*/
public Window getOppositeWindow() {
if (opposite == null) {
return null;
}
/*
return (SunToolkit.targetToAppContext(opposite) ==
AppContext.getAppContext())
? opposite
: null;
*/
return opposite;
}
/**
* For <code>WINDOW_STATE_CHANGED</code> events returns the
* previous state of the window. The state is
* represented as a bitwise mask.
* <ul>
* <li><code>NORMAL</code>
* <br>Indicates that no state bits are set.
* <li><code>ICONIFIED</code>
* <li><code>MAXIMIZED_HORIZ</code>
* <li><code>MAXIMIZED_VERT</code>
* <li><code>MAXIMIZED_BOTH</code>
* <br>Concatenates <code>MAXIMIZED_HORIZ</code>
* and <code>MAXIMIZED_VERT</code>.
* </ul>
*
* @return a bitwise mask of the previous window state
* @see java.awt.Frame#getExtendedState()
* @since 1.4
*/
public int getOldState() {
return oldState;
}
/**
* For <code>WINDOW_STATE_CHANGED</code> events returns the
* new state of the window. The state is
* represented as a bitwise mask.
* <ul>
* <li><code>NORMAL</code>
* <br>Indicates that no state bits are set.
* <li><code>ICONIFIED</code>
* <li><code>MAXIMIZED_HORIZ</code>
* <li><code>MAXIMIZED_VERT</code>
* <li><code>MAXIMIZED_BOTH</code>
* <br>Concatenates <code>MAXIMIZED_HORIZ</code>
* and <code>MAXIMIZED_VERT</code>.
* </ul>
*
* @return a bitwise mask of the new window state
* @see java.awt.Frame#getExtendedState()
* @since 1.4
*/
public int getNewState() {
return newState;
}
/**
* Returns a parameter string identifying this event.
* This method is useful for event-logging and for debugging.
*
* @return a string identifying the event and its attributes
*/
public String paramString() {
String typeStr;
switch(0) { // id
case WINDOW_OPENED:
typeStr = "WINDOW_OPENED";
break;
case WINDOW_CLOSING:
typeStr = "WINDOW_CLOSING";
break;
case WINDOW_CLOSED:
typeStr = "WINDOW_CLOSED";
break;
case WINDOW_ICONIFIED:
typeStr = "WINDOW_ICONIFIED";
break;
case WINDOW_DEICONIFIED:
typeStr = "WINDOW_DEICONIFIED";
break;
case WINDOW_ACTIVATED:
typeStr = "WINDOW_ACTIVATED";
break;
case WINDOW_DEACTIVATED:
typeStr = "WINDOW_DEACTIVATED";
break;
case WINDOW_GAINED_FOCUS:
typeStr = "WINDOW_GAINED_FOCUS";
break;
case WINDOW_LOST_FOCUS:
typeStr = "WINDOW_LOST_FOCUS";
break;
case WINDOW_STATE_CHANGED:
typeStr = "WINDOW_STATE_CHANGED";
break;
default:
typeStr = "unknown type";
}
typeStr += ",opposite=" + getOppositeWindow()
+ ",oldState=" + oldState + ",newState=" + newState;
return typeStr;
}
}
@@ -0,0 +1,5 @@
package java.awt.event;
public interface WindowListener
{
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+330
View File
@@ -0,0 +1,330 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.util.NoSuchElementException;
import org.apache.harmony.awt.internal.nls.Messages;
import org.apache.harmony.luni.util.NotImplementedException;
/**
* The Class Area provides a minimal implementation for a generic shape.
*
* @since Android 1.0
*/
public class Area implements Shape, Cloneable {
/**
* The source Shape object.
*/
Shape s;
/**
* The Class NullIterator.
*/
private static class NullIterator implements PathIterator {
/**
* Instantiates a new null iterator.
*/
NullIterator() {
}
public int getWindingRule() {
return WIND_NON_ZERO;
}
public boolean isDone() {
return true;
}
public void next() {
// nothing
}
public int currentSegment(double[] coords) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
public int currentSegment(float[] coords) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
}
/**
* Instantiates a new area with no data.
*/
public Area() {
}
/**
* Instantiates a new area with data given by the specified shape.
*
* @param s
* the shape that gives the data for this Area.
*/
public Area(Shape s) {
if (s == null) {
throw new NullPointerException();
}
this.s = s;
}
public boolean contains(double x, double y) {
return s == null ? false : s.contains(x, y);
}
public boolean contains(double x, double y, double width, double height) {
return s == null ? false : s.contains(x, y, width, height);
}
public boolean contains(Point2D p) {
if (p == null) {
throw new NullPointerException();
}
return s == null ? false : s.contains(p);
}
public boolean contains(Rectangle2D r) {
if (r == null) {
throw new NullPointerException();
}
return s == null ? false : s.contains(r);
}
/**
* Tests whether the object is equal to this Area.
*
* @param obj
* the object to compare.
* @return true, if successful.
* @throws NotImplementedException
* if this method is not implemented.
*/
public boolean equals(Area obj) throws org.apache.harmony.luni.util.NotImplementedException {
throw new RuntimeException("Not implemented"); //$NON-NLS-1$
}
public boolean intersects(double x, double y, double width, double height) {
return s == null ? false : s.intersects(x, y, width, height);
}
public boolean intersects(Rectangle2D r) {
if (r == null) {
throw new NullPointerException();
}
return s == null ? false : s.intersects(r);
}
public Rectangle getBounds() {
return s == null ? new Rectangle() : s.getBounds();
}
public Rectangle2D getBounds2D() {
return s == null ? new Rectangle2D.Double() : s.getBounds2D();
}
public PathIterator getPathIterator(AffineTransform t) {
return s == null ? new NullIterator() : s.getPathIterator(t);
}
public PathIterator getPathIterator(AffineTransform t, double flatness) {
return s == null ? new NullIterator() : s.getPathIterator(t, flatness);
}
/**
* Adds the specified area to this area.
*
* @param area
* the area to add to this area.
* @throws NotImplementedException
* if this method is not implemented.
*/
public void add(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
throw new RuntimeException("Not implemented"); //$NON-NLS-1$
}
/**
* Performs an exclusive or operation between this shape and the specified
* shape.
*
* @param area
* the area to XOR against this area.
* @throws NotImplementedException
* if this method is not implemented.
*/
public void exclusiveOr(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
throw new RuntimeException("Not implemented"); //$NON-NLS-1$
}
/**
* Extracts a Rectangle2D from the source shape if the underlying shape data
* describes a rectangle.
*
* @return a Rectangle2D object if the source shape is rectangle, or null if
* shape is empty or not rectangle.
*/
Rectangle2D extractRectangle() {
if (s == null) {
return null;
}
float[] points = new float[12];
int count = 0;
PathIterator p = s.getPathIterator(null);
float[] coords = new float[6];
while (!p.isDone()) {
int type = p.currentSegment(coords);
if (count > 12 || type == PathIterator.SEG_QUADTO || type == PathIterator.SEG_CUBICTO) {
return null;
}
points[count++] = coords[0];
points[count++] = coords[1];
p.next();
}
if (points[0] == points[6] && points[6] == points[8] && points[2] == points[4]
&& points[1] == points[3] && points[3] == points[9] && points[5] == points[7]) {
return new Rectangle2D.Float(points[0], points[1], points[2] - points[0], points[7]
- points[1]);
}
return null;
}
/**
* Reduces the size of this Area by intersecting it with the specified Area
* if they are both rectangles.
*
* @see java.awt.geom.Rectangle2D#intersect(Rectangle2D, Rectangle2D,
* Rectangle2D)
* @param area
* the area.
*/
public void intersect(Area area) {
Rectangle2D src1 = extractRectangle();
Rectangle2D src2 = area.extractRectangle();
if (src1 != null && src2 != null) {
Rectangle2D.intersect(src1, src2, (Rectangle2D)s);
}
}
/**
* Subtract the specified area from this area.
*
* @param area
* the area to subtract.
* @throws NotImplementedException
* if this method is not implemented.
*/
public void subtract(Area area) throws org.apache.harmony.luni.util.NotImplementedException {
throw new RuntimeException("Not implemented"); //$NON-NLS-1$
}
/**
* Checks if this Area is empty.
*
* @return true, if this Area is empty.
* @throws NotImplementedException
* if this method is not implemented.
*/
public boolean isEmpty() throws org.apache.harmony.luni.util.NotImplementedException {
throw new RuntimeException("Not implemented"); //$NON-NLS-1$
}
/**
* Checks if this Area is polygonal.
*
* @return true, if this Area is polygonal.
* @throws NotImplementedException
* if this method is not implemented.
*/
public boolean isPolygonal() throws org.apache.harmony.luni.util.NotImplementedException {
throw new RuntimeException("Not implemented"); //$NON-NLS-1$
}
/**
* Checks if this Area is rectangular.
*
* @return true, if this Area is rectangular.
* @throws NotImplementedException
* if this method is not implemented.
*/
public boolean isRectangular() throws org.apache.harmony.luni.util.NotImplementedException {
throw new RuntimeException("Not implemented"); //$NON-NLS-1$
}
/**
* Checks if this Area is singular.
*
* @return true, if this Area is singular.
* @throws NotImplementedException
* if this method is not implemented.
*/
public boolean isSingular() throws org.apache.harmony.luni.util.NotImplementedException {
throw new RuntimeException("Not implemented"); //$NON-NLS-1$
}
/**
* Resets the data of this Area.
*
* @throws NotImplementedException
* if this method is not implemented.
*/
public void reset() throws org.apache.harmony.luni.util.NotImplementedException {
throw new RuntimeException("Not implemented"); //$NON-NLS-1$
}
/**
* Transforms the data of this Area according to the specified
* AffineTransform.
*
* @param t
* the transform to use to transform the data.
*/
public void transform(AffineTransform t) {
s = t.createTransformedShape(s);
}
/**
* Creates a new Area that is the result of transforming the data of this
* Area according to the specified AffineTransform.
*
* @param t
* the transform to use to transform the data.
* @return the new Area that is the result of transforming the data of this
* Area according to the specified AffineTransform.
*/
public Area createTransformedArea(AffineTransform t) {
return s == null ? new Area() : new Area(t.createTransformedShape(s));
}
@Override
public Object clone() {
return new Area(this);
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,83 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
/**
* The Class Dimension2D represents a size (width and height) of a geometric
* object. It stores double-valued data in order to be compatible with
* high-precision geometric operations.
*
* @since Android 1.0
*/
public abstract class Dimension2D implements Cloneable {
/**
* Instantiates a new dimension 2d with no data.
*/
protected Dimension2D() {
}
/**
* Gets the width.
*
* @return the width.
*/
public abstract double getWidth();
/**
* Gets the height.
*
* @return the height.
*/
public abstract double getHeight();
/**
* Sets the width and height.
*
* @param width
* the width.
* @param height
* the height.
*/
public abstract void setSize(double width, double height);
/**
* Sets the width and height based on the data of another Dimension2D
* object.
*
* @param d
* the Dimension2D object providing the data to copy into this
* Dimension2D object.
*/
public void setSize(Dimension2D d) {
setSize(d.getWidth(), d.getHeight());
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
}
@@ -0,0 +1,458 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
import java.util.NoSuchElementException;
import org.apache.harmony.awt.internal.nls.Messages;
/**
* The Class Ellipse2D describes an ellipse defined by a rectangular area in
* which it is inscribed.
*
* @since Android 1.0
*/
public abstract class Ellipse2D extends RectangularShape {
/**
* The Class Float is the subclass of Ellipse2D that has all of its data
* values stored with float-level precision.
*
* @since Android 1.0
*/
public static class Float extends Ellipse2D {
/**
* The x coordinate of the upper left corner of the ellipse's bounding
* rectangle.
*/
public float x;
/**
* The y coordinate of the upper left corner of the ellipse's bounding
* rectangle.
*/
public float y;
/**
* The width of the ellipse's bounding rectangle.
*/
public float width;
/**
* The height of the ellipse's bounding rectangle.
*/
public float height;
/**
* Instantiates a new float-valued Ellipse2D.
*/
public Float() {
}
/**
* Instantiates a new float-valued Ellipse2D with the specified data.
*
* @param x
* the x coordinate of the upper left corner of the ellipse's
* bounding rectangle.
* @param y
* the y coordinate of the upper left corner of the ellipse's
* bounding rectangle.
* @param width
* the width of the ellipse's bounding rectangle.
* @param height
* the height of the ellipse's bounding rectangle.
*/
public Float(float x, float y, float width, float height) {
setFrame(x, y, width, height);
}
@Override
public double getX() {
return x;
}
@Override
public double getY() {
return y;
}
@Override
public double getWidth() {
return width;
}
@Override
public double getHeight() {
return height;
}
@Override
public boolean isEmpty() {
return width <= 0.0 || height <= 0.0;
}
/**
* Sets the data of the ellipse's bounding rectangle.
*
* @param x
* the x coordinate of the upper left corner of the ellipse's
* bounding rectangle.
* @param y
* the y coordinate of the upper left corner of the ellipse's
* bounding rectangle.
* @param width
* the width of the ellipse's bounding rectangle.
* @param height
* the height of the ellipse's bounding rectangle.
*/
public void setFrame(float x, float y, float width, float height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
@Override
public void setFrame(double x, double y, double width, double height) {
this.x = (float)x;
this.y = (float)y;
this.width = (float)width;
this.height = (float)height;
}
public Rectangle2D getBounds2D() {
return new Rectangle2D.Float(x, y, width, height);
}
}
/**
* The Class Double is the subclass of Ellipse2D that has all of its data
* values stored with double-level precision.
*
* @since Android 1.0
*/
public static class Double extends Ellipse2D {
/**
* The x coordinate of the upper left corner of the ellipse's bounding
* rectangle.
*/
public double x;
/**
* The y coordinate of the upper left corner of the ellipse's bounding
* rectangle.
*/
public double y;
/**
* The width of the ellipse's bounding rectangle.
*/
public double width;
/**
* The height of the ellipse's bounding rectangle.
*/
public double height;
/**
* Instantiates a new double-valued Ellipse2D.
*/
public Double() {
}
/**
* Instantiates a new double-valued Ellipse2D with the specified data.
*
* @param x
* the x coordinate of the upper left corner of the ellipse's
* bounding rectangle.
* @param y
* the y coordinate of the upper left corner of the ellipse's
* bounding rectangle.
* @param width
* the width of the ellipse's bounding rectangle.
* @param height
* the height of the ellipse's bounding rectangle.
*/
public Double(double x, double y, double width, double height) {
setFrame(x, y, width, height);
}
@Override
public double getX() {
return x;
}
@Override
public double getY() {
return y;
}
@Override
public double getWidth() {
return width;
}
@Override
public double getHeight() {
return height;
}
@Override
public boolean isEmpty() {
return width <= 0.0 || height <= 0.0;
}
@Override
public void setFrame(double x, double y, double width, double height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
public Rectangle2D getBounds2D() {
return new Rectangle2D.Double(x, y, width, height);
}
}
/*
* Ellipse2D path iterator
*/
/**
* The subclass of PathIterator to traverse an Ellipse2D.
*/
class Iterator implements PathIterator {
/*
* Ellipse is subdivided into four quarters by x and y axis. Each part
* approximated by cubic Bezier curve. Arc in first quarter is started
* in (a, 0) and finished in (0, b) points. Control points for cubic
* curve wiil be (a, 0), (a, m), (n, b) and (0, b) where n and m are
* calculated based on requirement Bezier curve in point 0.5 should lay
* on the arc.
*/
/**
* The coefficient to calculate control points of Bezier curves.
*/
final double u = 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
/**
* The points coordinates calculation table.
*/
final double points[][] = {
{
1.0, 0.5 + u, 0.5 + u, 1.0, 0.5, 1.0
}, {
0.5 - u, 1.0, 0.0, 0.5 + u, 0.0, 0.5
}, {
0.0, 0.5 - u, 0.5 - u, 0.0, 0.5, 0.0
}, {
0.5 + u, 0.0, 1.0, 0.5 - u, 1.0, 0.5
}
};
/**
* The x coordinate of left-upper corner of the ellipse bounds.
*/
double x;
/**
* The y coordinate of left-upper corner of the ellipse bounds.
*/
double y;
/**
* The width of the ellipse bounds.
*/
double width;
/**
* The height of the ellipse bounds.
*/
double height;
/**
* The path iterator transformation.
*/
AffineTransform t;
/**
* The current segment index.
*/
int index;
/**
* Constructs a new Ellipse2D.Iterator for given ellipse and
* transformation
*
* @param e
* the source Ellipse2D object.
* @param t
* the affine transformation object.
*/
Iterator(Ellipse2D e, AffineTransform t) {
this.x = e.getX();
this.y = e.getY();
this.width = e.getWidth();
this.height = e.getHeight();
this.t = t;
if (width < 0.0 || height < 0.0) {
index = 6;
}
}
public int getWindingRule() {
return WIND_NON_ZERO;
}
public boolean isDone() {
return index > 5;
}
public void next() {
index++;
}
public int currentSegment(double[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
if (index == 5) {
return SEG_CLOSE;
}
int type;
int count;
if (index == 0) {
type = SEG_MOVETO;
count = 1;
double p[] = points[3];
coords[0] = x + p[4] * width;
coords[1] = y + p[5] * height;
} else {
type = SEG_CUBICTO;
count = 3;
double p[] = points[index - 1];
int j = 0;
for (int i = 0; i < 3; i++) {
coords[j] = x + p[j++] * width;
coords[j] = y + p[j++] * height;
}
}
if (t != null) {
t.transform(coords, 0, coords, 0, count);
}
return type;
}
public int currentSegment(float[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
if (index == 5) {
return SEG_CLOSE;
}
int type;
int count;
if (index == 0) {
type = SEG_MOVETO;
count = 1;
double p[] = points[3];
coords[0] = (float)(x + p[4] * width);
coords[1] = (float)(y + p[5] * height);
} else {
type = SEG_CUBICTO;
count = 3;
int j = 0;
double p[] = points[index - 1];
for (int i = 0; i < 3; i++) {
coords[j] = (float)(x + p[j++] * width);
coords[j] = (float)(y + p[j++] * height);
}
}
if (t != null) {
t.transform(coords, 0, coords, 0, count);
}
return type;
}
}
/**
* Instantiates a new Ellipse2D.
*/
protected Ellipse2D() {
}
public boolean contains(double px, double py) {
if (isEmpty()) {
return false;
}
double a = (px - getX()) / getWidth() - 0.5;
double b = (py - getY()) / getHeight() - 0.5;
return a * a + b * b < 0.25;
}
public boolean intersects(double rx, double ry, double rw, double rh) {
if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
return false;
}
double cx = getX() + getWidth() / 2.0;
double cy = getY() + getHeight() / 2.0;
double rx1 = rx;
double ry1 = ry;
double rx2 = rx + rw;
double ry2 = ry + rh;
double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
return contains(nx, ny);
}
public boolean contains(double rx, double ry, double rw, double rh) {
if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
return false;
}
double rx1 = rx;
double ry1 = ry;
double rx2 = rx + rw;
double ry2 = ry + rh;
return contains(rx1, ry1) && contains(rx2, ry1) && contains(rx2, ry2) && contains(rx1, ry2);
}
public PathIterator getPathIterator(AffineTransform at) {
return new Iterator(this, at);
}
}
@@ -0,0 +1,358 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
import java.util.NoSuchElementException;
import org.apache.harmony.awt.internal.nls.Messages;
/**
* The Class FlatteningPathIterator takes a PathIterator for traversing a curved
* shape and flattens it by estimating the curve as a series of line segments.
* The flattening factor indicates how far the estimating line segments are
* allowed to be from the actual curve: the FlatteningPathIterator will keep
* dividing each curved segment into smaller and smaller flat segments until
* either the segments are within the flattening factor of the curve or until
* the buffer limit is reached.
*
* @since Android 1.0
*/
public class FlatteningPathIterator implements PathIterator {
/**
* The default points buffer size.
*/
private static final int BUFFER_SIZE = 16;
/**
* The default curve subdivision limit.
*/
private static final int BUFFER_LIMIT = 16;
/**
* The points buffer capacity.
*/
private static final int BUFFER_CAPACITY = 16;
/**
* The type of current segment to be flat.
*/
int bufType;
/**
* The curve subdivision limit.
*/
int bufLimit;
/**
* The current points buffer size.
*/
int bufSize;
/**
* The inner cursor position in points buffer.
*/
int bufIndex;
/**
* The current subdivision count.
*/
int bufSubdiv;
/**
* The points buffer.
*/
double buf[];
/**
* The indicator of empty points buffer.
*/
boolean bufEmpty = true;
/**
* The source PathIterator.
*/
PathIterator p;
/**
* The flatness of new path.
*/
double flatness;
/**
* The square of flatness.
*/
double flatness2;
/**
* The x coordinate of previous path segment.
*/
double px;
/**
* The y coordinate of previous path segment.
*/
double py;
/**
* The temporary buffer for getting points from PathIterator.
*/
double coords[] = new double[6];
/**
* Instantiates a new flattening path iterator given the path iterator for a
* (possibly) curved path and a flattening factor which indicates how close
* together the points on the curve should be chosen. The buffer limit
* defaults to 16 which means that each curve will be divided into no more
* than 16 segments regardless of the flattening factor.
*
* @param path
* the path iterator of the original curve.
* @param flatness
* the flattening factor that indicates how far the flat path is
* allowed to be from the actual curve in order to decide when to
* stop dividing the path into smaller and smaller segments.
* @throws IllegalArgumentException
* if the flatness is less than zero.
* @throws NullPointerException
* if the path is null.
*/
public FlatteningPathIterator(PathIterator path, double flatness) {
this(path, flatness, BUFFER_LIMIT);
}
/**
* Instantiates a new flattening path iterator given the path iterator for a
* (possibly) curved path and a flattening factor and a buffer limit. The
* FlatteningPathIterator will keep dividing each curved segment into
* smaller and smaller flat segments until either the segments are within
* the flattening factor of the curve or until the buffer limit is reached.
*
* @param path
* the path iterator of the original curve.
* @param flatness
* the flattening factor that indicates how far the flat path is
* allowed to be from the actual curve in order to decide when to
* stop dividing the path into smaller and smaller segments.
* @param limit
* the maximum number of flat segments to divide each curve into.
* @throws IllegalArgumentException
* if the flatness or limit is less than zero.
* @throws NullPointerException
* if the path is null.
*/
public FlatteningPathIterator(PathIterator path, double flatness, int limit) {
if (flatness < 0.0) {
// awt.206=Flatness is less then zero
throw new IllegalArgumentException(Messages.getString("awt.206")); //$NON-NLS-1$
}
if (limit < 0) {
// awt.207=Limit is less then zero
throw new IllegalArgumentException(Messages.getString("awt.207")); //$NON-NLS-1$
}
if (path == null) {
// awt.208=Path is null
throw new NullPointerException(Messages.getString("awt.208")); //$NON-NLS-1$
}
this.p = path;
this.flatness = flatness;
this.flatness2 = flatness * flatness;
this.bufLimit = limit;
this.bufSize = Math.min(bufLimit, BUFFER_SIZE);
this.buf = new double[bufSize];
this.bufIndex = bufSize;
}
/**
* Gets the flattening factor.
*
* @return the flattening factor.
*/
public double getFlatness() {
return flatness;
}
/**
* Gets the maximum number of subdivisions per curved segment.
*
* @return the maximum number of subdivisions per curved segment.
*/
public int getRecursionLimit() {
return bufLimit;
}
public int getWindingRule() {
return p.getWindingRule();
}
public boolean isDone() {
return bufEmpty && p.isDone();
}
/**
* Calculates flat path points for current segment of the source shape. Line
* segment is flat by itself. Flatness of quad and cubic curves evaluated by
* getFlatnessSq() method. Curves subdivided until current flatness is
* bigger than user defined and subdivision limit isn't exhausted. Single
* source segment translated to series of buffer points. The less flatness
* the bigger series. Every currentSegment() call extract one point from the
* buffer. When series completed evaluate() takes next source shape segment.
*/
void evaluate() {
if (bufEmpty) {
bufType = p.currentSegment(coords);
}
switch (bufType) {
case SEG_MOVETO:
case SEG_LINETO:
px = coords[0];
py = coords[1];
break;
case SEG_QUADTO:
if (bufEmpty) {
bufIndex -= 6;
buf[bufIndex + 0] = px;
buf[bufIndex + 1] = py;
System.arraycopy(coords, 0, buf, bufIndex + 2, 4);
bufSubdiv = 0;
}
while (bufSubdiv < bufLimit) {
if (QuadCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
break;
}
// Realloc buffer
if (bufIndex <= 4) {
double tmp[] = new double[bufSize + BUFFER_CAPACITY];
System.arraycopy(buf, bufIndex, tmp, bufIndex + BUFFER_CAPACITY, bufSize
- bufIndex);
buf = tmp;
bufSize += BUFFER_CAPACITY;
bufIndex += BUFFER_CAPACITY;
}
QuadCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 4, buf, bufIndex);
bufIndex -= 4;
bufSubdiv++;
}
bufIndex += 4;
px = buf[bufIndex];
py = buf[bufIndex + 1];
bufEmpty = (bufIndex == bufSize - 2);
if (bufEmpty) {
bufIndex = bufSize;
bufType = SEG_LINETO;
} else {
bufSubdiv--;
}
break;
case SEG_CUBICTO:
if (bufEmpty) {
bufIndex -= 8;
buf[bufIndex + 0] = px;
buf[bufIndex + 1] = py;
System.arraycopy(coords, 0, buf, bufIndex + 2, 6);
bufSubdiv = 0;
}
while (bufSubdiv < bufLimit) {
if (CubicCurve2D.getFlatnessSq(buf, bufIndex) < flatness2) {
break;
}
// Realloc buffer
if (bufIndex <= 6) {
double tmp[] = new double[bufSize + BUFFER_CAPACITY];
System.arraycopy(buf, bufIndex, tmp, bufIndex + BUFFER_CAPACITY, bufSize
- bufIndex);
buf = tmp;
bufSize += BUFFER_CAPACITY;
bufIndex += BUFFER_CAPACITY;
}
CubicCurve2D.subdivide(buf, bufIndex, buf, bufIndex - 6, buf, bufIndex);
bufIndex -= 6;
bufSubdiv++;
}
bufIndex += 6;
px = buf[bufIndex];
py = buf[bufIndex + 1];
bufEmpty = (bufIndex == bufSize - 2);
if (bufEmpty) {
bufIndex = bufSize;
bufType = SEG_LINETO;
} else {
bufSubdiv--;
}
break;
}
}
public void next() {
if (bufEmpty) {
p.next();
}
}
public int currentSegment(float[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4Bx")); //$NON-NLS-1$
}
evaluate();
int type = bufType;
if (type != SEG_CLOSE) {
coords[0] = (float)px;
coords[1] = (float)py;
if (type != SEG_MOVETO) {
type = SEG_LINETO;
}
}
return type;
}
public int currentSegment(double[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
evaluate();
int type = bufType;
if (type != SEG_CLOSE) {
coords[0] = px;
coords[1] = py;
if (type != SEG_MOVETO) {
type = SEG_LINETO;
}
}
return type;
}
}
@@ -0,0 +1,624 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
import java.awt.Rectangle;
import java.awt.Shape;
import java.util.NoSuchElementException;
import org.apache.harmony.awt.gl.Crossing;
import org.apache.harmony.awt.internal.nls.Messages;
/**
* The class GeneralPath represents a shape whose outline is given by different
* types of curved and straight segments.
*
* @since Android 1.0
*/
public final class GeneralPath implements Shape, Cloneable {
/**
* The Constant WIND_EVEN_ODD see {@link PathIterator#WIND_EVEN_ODD}.
*/
public static final int WIND_EVEN_ODD = PathIterator.WIND_EVEN_ODD;
/**
* The Constant WIND_NON_ZERO see {@link PathIterator#WIND_NON_ZERO}.
*/
public static final int WIND_NON_ZERO = PathIterator.WIND_NON_ZERO;
/**
* The buffers size.
*/
private static final int BUFFER_SIZE = 10;
/**
* The buffers capacity.
*/
private static final int BUFFER_CAPACITY = 10;
/**
* The point's types buffer.
*/
byte[] types;
/**
* The points buffer.
*/
float[] points;
/**
* The point's type buffer size.
*/
int typeSize;
/**
* The points buffer size.
*/
int pointSize;
/**
* The path rule.
*/
int rule;
/**
* The space amount in points buffer for different segmenet's types.
*/
static int pointShift[] = {
2, // MOVETO
2, // LINETO
4, // QUADTO
6, // CUBICTO
0
}; // CLOSE
/*
* GeneralPath path iterator
*/
/**
* The Class Iterator is the subclass of Iterator for traversing the outline
* of a GeneralPath.
*/
class Iterator implements PathIterator {
/**
* The current cursor position in types buffer.
*/
int typeIndex;
/**
* The current cursor position in points buffer.
*/
int pointIndex;
/**
* The source GeneralPath object.
*/
GeneralPath p;
/**
* The path iterator transformation.
*/
AffineTransform t;
/**
* Constructs a new GeneralPath.Iterator for given general path.
*
* @param path
* the source GeneralPath object.
*/
Iterator(GeneralPath path) {
this(path, null);
}
/**
* Constructs a new GeneralPath.Iterator for given general path and
* transformation.
*
* @param path
* the source GeneralPath object.
* @param at
* the AffineTransform object to apply rectangle path.
*/
Iterator(GeneralPath path, AffineTransform at) {
this.p = path;
this.t = at;
}
public int getWindingRule() {
return p.getWindingRule();
}
public boolean isDone() {
return typeIndex >= p.typeSize;
}
public void next() {
typeIndex++;
}
public int currentSegment(double[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
int type = p.types[typeIndex];
int count = GeneralPath.pointShift[type];
for (int i = 0; i < count; i++) {
coords[i] = p.points[pointIndex + i];
}
if (t != null) {
t.transform(coords, 0, coords, 0, count / 2);
}
pointIndex += count;
return type;
}
public int currentSegment(float[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
int type = p.types[typeIndex];
int count = GeneralPath.pointShift[type];
System.arraycopy(p.points, pointIndex, coords, 0, count);
if (t != null) {
t.transform(coords, 0, coords, 0, count / 2);
}
pointIndex += count;
return type;
}
}
/**
* Instantiates a new general path with the winding rule set to
* {@link PathIterator#WIND_NON_ZERO} and the initial capacity (number of
* segments) set to the default value 10.
*/
public GeneralPath() {
this(WIND_NON_ZERO, BUFFER_SIZE);
}
/**
* Instantiates a new general path with the given winding rule and the
* initial capacity (number of segments) set to the default value 10.
*
* @param rule
* the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
* {@link PathIterator#WIND_NON_ZERO}.
*/
public GeneralPath(int rule) {
this(rule, BUFFER_SIZE);
}
/**
* Instantiates a new general path with the given winding rule and initial
* capacity (number of segments).
*
* @param rule
* the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
* {@link PathIterator#WIND_NON_ZERO}.
* @param initialCapacity
* the number of segments the path is set to hold.
*/
public GeneralPath(int rule, int initialCapacity) {
setWindingRule(rule);
types = new byte[initialCapacity];
points = new float[initialCapacity * 2];
}
/**
* Creates a new GeneralPath from the outline of the given shape.
*
* @param shape
* the shape.
*/
public GeneralPath(Shape shape) {
this(WIND_NON_ZERO, BUFFER_SIZE);
PathIterator p = shape.getPathIterator(null);
setWindingRule(p.getWindingRule());
append(p, false);
}
/**
* Sets the winding rule, which determines how to decide whether a point
* that isn't on the path itself is inside or outside of the shape.
*
* @param rule
* the new winding rule.
* @throws IllegalArgumentException
* if the winding rule is neither
* {@link PathIterator#WIND_EVEN_ODD} nor
* {@link PathIterator#WIND_NON_ZERO}.
*/
public void setWindingRule(int rule) {
if (rule != WIND_EVEN_ODD && rule != WIND_NON_ZERO) {
// awt.209=Invalid winding rule value
throw new java.lang.IllegalArgumentException(Messages.getString("awt.209")); //$NON-NLS-1$
}
this.rule = rule;
}
/**
* Gets the winding rule.
*
* @return the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
* {@link PathIterator#WIND_NON_ZERO}.
*/
public int getWindingRule() {
return rule;
}
/**
* Checks the point data buffer sizes to see whether pointCount additional
* point-data elements can fit. (Note that the number of point data elements
* to add is more than one per point -- it depends on the type of point
* being added.) Reallocates the buffers to enlarge the size if necessary.
*
* @param pointCount
* the number of point data elements to be added.
* @param checkMove
* whether to check for existing points.
* @throws IllegalPathStateException
* checkMove is true and the path is currently empty.
*/
void checkBuf(int pointCount, boolean checkMove) {
if (checkMove && typeSize == 0) {
// awt.20A=First segment should be SEG_MOVETO type
throw new IllegalPathStateException(Messages.getString("awt.20A")); //$NON-NLS-1$
}
if (typeSize == types.length) {
byte tmp[] = new byte[typeSize + BUFFER_CAPACITY];
System.arraycopy(types, 0, tmp, 0, typeSize);
types = tmp;
}
if (pointSize + pointCount > points.length) {
float tmp[] = new float[pointSize + Math.max(BUFFER_CAPACITY * 2, pointCount)];
System.arraycopy(points, 0, tmp, 0, pointSize);
points = tmp;
}
}
/**
* Appends a new point to the end of this general path, disconnected from
* the existing path.
*
* @param x
* the x coordinate of the next point to append.
* @param y
* the y coordinate of the next point to append.
*/
public void moveTo(float x, float y) {
if (typeSize > 0 && types[typeSize - 1] == PathIterator.SEG_MOVETO) {
points[pointSize - 2] = x;
points[pointSize - 1] = y;
} else {
checkBuf(2, false);
types[typeSize++] = PathIterator.SEG_MOVETO;
points[pointSize++] = x;
points[pointSize++] = y;
}
}
/**
* Appends a new segment to the end of this general path by making a
* straight line segment from the current endpoint to the given new point.
*
* @param x
* the x coordinate of the next point to append.
* @param y
* the y coordinate of the next point to append.
*/
public void lineTo(float x, float y) {
checkBuf(2, true);
types[typeSize++] = PathIterator.SEG_LINETO;
points[pointSize++] = x;
points[pointSize++] = y;
}
/**
* Appends a new segment to the end of this general path by making a
* quadratic curve from the current endpoint to the point (x2, y2) using the
* point (x1, y1) as the quadratic curve's control point.
*
* @param x1
* the x coordinate of the quadratic curve's control point.
* @param y1
* the y coordinate of the quadratic curve's control point.
* @param x2
* the x coordinate of the quadratic curve's end point.
* @param y2
* the y coordinate of the quadratic curve's end point.
*/
public void quadTo(float x1, float y1, float x2, float y2) {
checkBuf(4, true);
types[typeSize++] = PathIterator.SEG_QUADTO;
points[pointSize++] = x1;
points[pointSize++] = y1;
points[pointSize++] = x2;
points[pointSize++] = y2;
}
/**
* Appends a new segment to the end of this general path by making a cubic
* curve from the current endpoint to the point (x3, y3) using (x1, y1) and
* (x2, y2) as control points.
*
* @see java.awt.geom.CubicCurve2D
* @param x1
* the x coordinate of the new cubic segment's first control
* point.
* @param y1
* the y coordinate of the new cubic segment's first control
* point.
* @param x2
* the x coordinate of the new cubic segment's second control
* point.
* @param y2
* the y coordinate of the new cubic segment's second control
* point.
* @param x3
* the x coordinate of the new cubic segment's end point.
* @param y3
* the y coordinate of the new cubic segment's end point.
*/
public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) {
checkBuf(6, true);
types[typeSize++] = PathIterator.SEG_CUBICTO;
points[pointSize++] = x1;
points[pointSize++] = y1;
points[pointSize++] = x2;
points[pointSize++] = y2;
points[pointSize++] = x3;
points[pointSize++] = y3;
}
/**
* Appends the type information to declare that the current endpoint closes
* the curve.
*/
public void closePath() {
if (typeSize == 0 || types[typeSize - 1] != PathIterator.SEG_CLOSE) {
checkBuf(0, true);
types[typeSize++] = PathIterator.SEG_CLOSE;
}
}
/**
* Appends the outline of the specified shape onto the end of this
* GeneralPath.
*
* @param shape
* the shape whose outline is to be appended.
* @param connect
* true to connect this path's current endpoint to the first
* point of the shape's outline or false to append the shape's
* outline without connecting it.
* @throws NullPointerException
* if the shape parameter is null.
*/
public void append(Shape shape, boolean connect) {
PathIterator p = shape.getPathIterator(null);
append(p, connect);
}
/**
* Appends the path defined by the specified PathIterator onto the end of
* this GeneralPath.
*
* @param path
* the PathIterator that defines the new path to append.
* @param connect
* true to connect this path's current endpoint to the first
* point of the shape's outline or false to append the shape's
* outline without connecting it.
*/
public void append(PathIterator path, boolean connect) {
while (!path.isDone()) {
float coords[] = new float[6];
switch (path.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
if (!connect || typeSize == 0) {
moveTo(coords[0], coords[1]);
break;
}
if (types[typeSize - 1] != PathIterator.SEG_CLOSE
&& points[pointSize - 2] == coords[0]
&& points[pointSize - 1] == coords[1]) {
break;
}
// NO BREAK;
case PathIterator.SEG_LINETO:
lineTo(coords[0], coords[1]);
break;
case PathIterator.SEG_QUADTO:
quadTo(coords[0], coords[1], coords[2], coords[3]);
break;
case PathIterator.SEG_CUBICTO:
curveTo(coords[0], coords[1], coords[2], coords[3], coords[4], coords[5]);
break;
case PathIterator.SEG_CLOSE:
closePath();
break;
}
path.next();
connect = false;
}
}
/**
* Gets the current end point of the path.
*
* @return the current end point of the path.
*/
public Point2D getCurrentPoint() {
if (typeSize == 0) {
return null;
}
int j = pointSize - 2;
if (types[typeSize - 1] == PathIterator.SEG_CLOSE) {
for (int i = typeSize - 2; i > 0; i--) {
int type = types[i];
if (type == PathIterator.SEG_MOVETO) {
break;
}
j -= pointShift[type];
}
}
return new Point2D.Float(points[j], points[j + 1]);
}
/**
* Resets the GeneralPath to being an empty path. The underlying point and
* segment data is not deleted but rather the end indices of the data arrays
* are set to zero.
*/
public void reset() {
typeSize = 0;
pointSize = 0;
}
/**
* Transform all of the coordinates of this path according to the specified
* AffineTransform.
*
* @param t
* the AffineTransform.
*/
public void transform(AffineTransform t) {
t.transform(points, 0, points, 0, pointSize / 2);
}
/**
* Creates a new GeneralPath whose data is given by this path's data
* transformed according to the specified AffineTransform.
*
* @param t
* the AffineTransform.
* @return the new GeneralPath whose data is given by this path's data
* transformed according to the specified AffineTransform.
*/
public Shape createTransformedShape(AffineTransform t) {
GeneralPath p = (GeneralPath)clone();
if (t != null) {
p.transform(t);
}
return p;
}
public Rectangle2D getBounds2D() {
float rx1, ry1, rx2, ry2;
if (pointSize == 0) {
rx1 = ry1 = rx2 = ry2 = 0.0f;
} else {
int i = pointSize - 1;
ry1 = ry2 = points[i--];
rx1 = rx2 = points[i--];
while (i > 0) {
float y = points[i--];
float x = points[i--];
if (x < rx1) {
rx1 = x;
} else if (x > rx2) {
rx2 = x;
}
if (y < ry1) {
ry1 = y;
} else if (y > ry2) {
ry2 = y;
}
}
}
return new Rectangle2D.Float(rx1, ry1, rx2 - rx1, ry2 - ry1);
}
public Rectangle getBounds() {
return getBounds2D().getBounds();
}
/**
* Checks the cross count (number of times a ray from the point crosses the
* shape's boundary) to determine whether the number of crossings
* corresponds to a point inside the shape or not (according to the shape's
* path rule).
*
* @param cross
* the point's cross count.
* @return true if the point is inside the path, or false otherwise.
*/
boolean isInside(int cross) {
if (rule == WIND_NON_ZERO) {
return Crossing.isInsideNonZero(cross);
}
return Crossing.isInsideEvenOdd(cross);
}
public boolean contains(double px, double py) {
return isInside(Crossing.crossShape(this, px, py));
}
public boolean contains(double rx, double ry, double rw, double rh) {
int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
return cross != Crossing.CROSSING && isInside(cross);
}
public boolean intersects(double rx, double ry, double rw, double rh) {
int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
return cross == Crossing.CROSSING || isInside(cross);
}
public boolean contains(Point2D p) {
return contains(p.getX(), p.getY());
}
public boolean contains(Rectangle2D r) {
return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
public boolean intersects(Rectangle2D r) {
return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
public PathIterator getPathIterator(AffineTransform t) {
return new Iterator(this, t);
}
public PathIterator getPathIterator(AffineTransform t, double flatness) {
return new FlatteningPathIterator(getPathIterator(t), flatness);
}
@Override
public Object clone() {
try {
GeneralPath p = (GeneralPath)super.clone();
p.types = types.clone();
p.points = points.clone();
return p;
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
}
@@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
/**
* The Class IllegalPathStateException indicates errors where the current state
* of a path object is incompatible with the desired action, such as performing
* non-trivial actions on an empty path.
*
* @since Android 1.0
*/
public class IllegalPathStateException extends RuntimeException {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = -5158084205220481094L;
/**
* Instantiates a new illegal path state exception.
*/
public IllegalPathStateException() {
}
/**
* Instantiates a new illegal path state exception with the specified detail
* message.
*
* @param s
* the details of the error.
*/
public IllegalPathStateException(String s) {
super(s);
}
}
+948
View File
@@ -0,0 +1,948 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
import java.awt.Rectangle;
import java.awt.Shape;
import java.util.NoSuchElementException;
import org.apache.harmony.awt.internal.nls.Messages;
/**
* The Class Line2D represents a line whose data is given in high-precision
* values appropriate for graphical operations.
*
* @since Android 1.0
*/
public abstract class Line2D implements Shape, Cloneable {
/**
* The Class Float is the subclass of Line2D that has all of its data values
* stored with float-level precision.
*
* @since Android 1.0
*/
public static class Float extends Line2D {
/**
* The x coordinate of the starting point.
*/
public float x1;
/**
* The y coordinate of the starting point.
*/
public float y1;
/**
* The x coordinate of the end point.
*/
public float x2;
/**
* The y coordinate of the end point.
*/
public float y2;
/**
* Instantiates a new float-valued Line2D with its data values set to
* zero.
*/
public Float() {
}
/**
* Instantiates a new float-valued Line2D with the specified endpoints.
*
* @param x1
* the x coordinate of the starting point.
* @param y1
* the y coordinate of the starting point.
* @param x2
* the x coordinate of the end point.
* @param y2
* the y coordinate of the end point.
*/
public Float(float x1, float y1, float x2, float y2) {
setLine(x1, y1, x2, y2);
}
/**
* Instantiates a new float-valued Line2D with the specified endpoints.
*
* @param p1
* the starting point.
* @param p2
* the end point.
*/
public Float(Point2D p1, Point2D p2) {
setLine(p1, p2);
}
@Override
public double getX1() {
return x1;
}
@Override
public double getY1() {
return y1;
}
@Override
public double getX2() {
return x2;
}
@Override
public double getY2() {
return y2;
}
@Override
public Point2D getP1() {
return new Point2D.Float(x1, y1);
}
@Override
public Point2D getP2() {
return new Point2D.Float(x2, y2);
}
@Override
public void setLine(double x1, double y1, double x2, double y2) {
this.x1 = (float)x1;
this.y1 = (float)y1;
this.x2 = (float)x2;
this.y2 = (float)y2;
}
/**
* Sets the data values that define the line.
*
* @param x1
* the x coordinate of the starting point.
* @param y1
* the y coordinate of the starting point.
* @param x2
* the x coordinate of the end point.
* @param y2
* the y coordinate of the end point.
*/
public void setLine(float x1, float y1, float x2, float y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
public Rectangle2D getBounds2D() {
float rx, ry, rw, rh;
if (x1 < x2) {
rx = x1;
rw = x2 - x1;
} else {
rx = x2;
rw = x1 - x2;
}
if (y1 < y2) {
ry = y1;
rh = y2 - y1;
} else {
ry = y2;
rh = y1 - y2;
}
return new Rectangle2D.Float(rx, ry, rw, rh);
}
}
/**
* The Class Double is the subclass of Line2D that has all of its data
* values stored with double-level precision.
*
* @since Android 1.0
*/
public static class Double extends Line2D {
/**
* The x coordinate of the starting point.
*/
public double x1;
/**
* The y coordinate of the starting point.
*/
public double y1;
/**
* The x coordinate of the end point.
*/
public double x2;
/**
* The y coordinate of the end point.
*/
public double y2;
/**
* Instantiates a new double-valued Line2D with its data values set to
* zero.
*/
public Double() {
}
/**
* Instantiates a new double-valued Line2D with the specified endpoints.
*
* @param x1
* the x coordinate of the starting point.
* @param y1
* the y coordinate of the starting point.
* @param x2
* the x coordinate of the end point.
* @param y2
* the y coordinate of the end point.
*/
public Double(double x1, double y1, double x2, double y2) {
setLine(x1, y1, x2, y2);
}
/**
* Instantiates a new double-valued Line2D with the specified endpoints.
*
* @param p1
* the starting point.
* @param p2
* the end point.
*/
public Double(Point2D p1, Point2D p2) {
setLine(p1, p2);
}
@Override
public double getX1() {
return x1;
}
@Override
public double getY1() {
return y1;
}
@Override
public double getX2() {
return x2;
}
@Override
public double getY2() {
return y2;
}
@Override
public Point2D getP1() {
return new Point2D.Double(x1, y1);
}
@Override
public Point2D getP2() {
return new Point2D.Double(x2, y2);
}
@Override
public void setLine(double x1, double y1, double x2, double y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
public Rectangle2D getBounds2D() {
double rx, ry, rw, rh;
if (x1 < x2) {
rx = x1;
rw = x2 - x1;
} else {
rx = x2;
rw = x1 - x2;
}
if (y1 < y2) {
ry = y1;
rh = y2 - y1;
} else {
ry = y2;
rh = y1 - y2;
}
return new Rectangle2D.Double(rx, ry, rw, rh);
}
}
/*
* Line2D path iterator
*/
/**
* The subclass of PathIterator to traverse a Line2D.
*/
class Iterator implements PathIterator {
/**
* The x coordinate of the start line point.
*/
double x1;
/**
* The y coordinate of the start line point.
*/
double y1;
/**
* The x coordinate of the end line point.
*/
double x2;
/**
* The y coordinate of the end line point.
*/
double y2;
/**
* The path iterator transformation.
*/
AffineTransform t;
/**
* The current segment index.
*/
int index;
/**
* Constructs a new Line2D.Iterator for given line and transformation.
*
* @param l
* the source Line2D object.
* @param at
* the AffineTransform object to apply rectangle path.
*/
Iterator(Line2D l, AffineTransform at) {
this.x1 = l.getX1();
this.y1 = l.getY1();
this.x2 = l.getX2();
this.y2 = l.getY2();
this.t = at;
}
public int getWindingRule() {
return WIND_NON_ZERO;
}
public boolean isDone() {
return index > 1;
}
public void next() {
index++;
}
public int currentSegment(double[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
int type;
if (index == 0) {
type = SEG_MOVETO;
coords[0] = x1;
coords[1] = y1;
} else {
type = SEG_LINETO;
coords[0] = x2;
coords[1] = y2;
}
if (t != null) {
t.transform(coords, 0, coords, 0, 1);
}
return type;
}
public int currentSegment(float[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
int type;
if (index == 0) {
type = SEG_MOVETO;
coords[0] = (float)x1;
coords[1] = (float)y1;
} else {
type = SEG_LINETO;
coords[0] = (float)x2;
coords[1] = (float)y2;
}
if (t != null) {
t.transform(coords, 0, coords, 0, 1);
}
return type;
}
}
/**
* Instantiates a new Line2D.
*/
protected Line2D() {
}
/**
* Gets the x coordinate of the starting point.
*
* @return the x coordinate of the starting point.
*/
public abstract double getX1();
/**
* Gets the y coordinate of the starting point.
*
* @return the y coordinate of the starting point.
*/
public abstract double getY1();
/**
* Gets the x coordinate of the end point.
*
* @return the x2.
*/
public abstract double getX2();
/**
* Gets the y coordinate of the end point.
*
* @return the y coordinate of the end point.
*/
public abstract double getY2();
/**
* Gets the p the starting point.
*
* @return the p the starting point.
*/
public abstract Point2D getP1();
/**
* Gets the p end point.
*
* @return the p end point.
*/
public abstract Point2D getP2();
/**
* Sets the line's endpoints.
*
* @param x1
* the x coordinate of the starting point.
* @param y1
* the y coordinate of the starting point.
* @param x2
* the x coordinate of the end point.
* @param y2
* the y coordinate of the end point.
*/
public abstract void setLine(double x1, double y1, double x2, double y2);
/**
* Sets the line's endpoints.
*
* @param p1
* the starting point.
* @param p2
* the end point.
*/
public void setLine(Point2D p1, Point2D p2) {
setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
}
/**
* Sets the line's endpoints by copying the data from another Line2D.
*
* @param line
* the Line2D to copy the endpoint data from.
*/
public void setLine(Line2D line) {
setLine(line.getX1(), line.getY1(), line.getX2(), line.getY2());
}
public Rectangle getBounds() {
return getBounds2D().getBounds();
}
/**
* Tells where the point is with respect to the line segment, given the
* orientation of the line segment. If the ray found by extending the line
* segment from its starting point is rotated, this method tells whether the
* ray should rotate in a clockwise direction or a counter-clockwise
* direction to hit the point first. The return value is 0 if the point is
* on the line segment, it's 1 if the point is on the ray or if the ray
* should rotate in a counter-clockwise direction to get to the point, and
* it's -1 if the ray should rotate in a clockwise direction to get to the
* point or if the point is on the line determined by the line segment but
* not on the ray from the segment's starting point and through its end
* point.
*
* @param x1
* the x coordinate of the starting point of the line segment.
* @param y1
* the y coordinate of the starting point of the line segment.
* @param x2
* the x coordinate of the end point of the line segment.
* @param y2
* the y coordinate of the end point of the line segment.
* @param px
* the x coordinate of the test point.
* @param py
* the p coordinate of the test point.
* @return the value that describes where the point is with respect to the
* line segment, given the orientation of the line segment.
*/
public static int relativeCCW(double x1, double y1, double x2, double y2, double px, double py) {
/*
* A = (x2-x1, y2-y1) P = (px-x1, py-y1)
*/
x2 -= x1;
y2 -= y1;
px -= x1;
py -= y1;
double t = px * y2 - py * x2; // PxA
if (t == 0.0) {
t = px * x2 + py * y2; // P*A
if (t > 0.0) {
px -= x2; // B-A
py -= y2;
t = px * x2 + py * y2; // (P-A)*A
if (t < 0.0) {
t = 0.0;
}
}
}
return t < 0.0 ? -1 : (t > 0.0 ? 1 : 0);
}
/**
* Tells where the point is with respect to this line segment, given the
* orientation of this line segment. If the ray found by extending the line
* segment from its starting point is rotated, this method tells whether the
* ray should rotate in a clockwise direction or a counter-clockwise
* direction to hit the point first. The return value is 0 if the point is
* on the line segment, it's 1 if the point is on the ray or if the ray
* should rotate in a counter-clockwise direction to get to the point, and
* it's -1 if the ray should rotate in a clockwise direction to get to the
* point or if the point is on the line determined by the line segment but
* not on the ray from the segment's starting point and through its end
* point.
*
* @param px
* the x coordinate of the test point.
* @param py
* the p coordinate of the test point.
* @return the value that describes where the point is with respect to this
* line segment, given the orientation of this line segment.
*/
public int relativeCCW(double px, double py) {
return relativeCCW(getX1(), getY1(), getX2(), getY2(), px, py);
}
/**
* Tells where the point is with respect to this line segment, given the
* orientation of this line segment. If the ray found by extending the line
* segment from its starting point is rotated, this method tells whether the
* ray should rotate in a clockwise direction or a counter-clockwise
* direction to hit the point first. The return value is 0 if the point is
* on the line segment, it's 1 if the point is on the ray or if the ray
* should rotate in a counter-clockwise direction to get to the point, and
* it's -1 if the ray should rotate in a clockwise direction to get to the
* point or if the point is on the line determined by the line segment but
* not on the ray from the segment's starting point and through its end
* point.
*
* @param p
* the test point.
* @return the value that describes where the point is with respect to this
* line segment, given the orientation of this line segment.
*/
public int relativeCCW(Point2D p) {
return relativeCCW(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
}
/**
* Tells whether the two line segments cross.
*
* @param x1
* the x coordinate of the starting point of the first segment.
* @param y1
* the y coordinate of the starting point of the first segment.
* @param x2
* the x coordinate of the end point of the first segment.
* @param y2
* the y coordinate of the end point of the first segment.
* @param x3
* the x coordinate of the starting point of the second segment.
* @param y3
* the y coordinate of the starting point of the second segment.
* @param x4
* the x coordinate of the end point of the second segment.
* @param y4
* the y coordinate of the end point of the second segment.
* @return true, if the two line segments cross.
*/
public static boolean linesIntersect(double x1, double y1, double x2, double y2, double x3,
double y3, double x4, double y4) {
/*
* A = (x2-x1, y2-y1) B = (x3-x1, y3-y1) C = (x4-x1, y4-y1) D = (x4-x3,
* y4-y3) = C-B E = (x1-x3, y1-y3) = -B F = (x2-x3, y2-y3) = A-B Result
* is ((AxB) (AxC) <=0) and ((DxE) (DxF) <= 0) DxE = (C-B)x(-B) =
* BxB-CxB = BxC DxF = (C-B)x(A-B) = CxA-CxB-BxA+BxB = AxB+BxC-AxC
*/
x2 -= x1; // A
y2 -= y1;
x3 -= x1; // B
y3 -= y1;
x4 -= x1; // C
y4 -= y1;
double AvB = x2 * y3 - x3 * y2;
double AvC = x2 * y4 - x4 * y2;
// Online
if (AvB == 0.0 && AvC == 0.0) {
if (x2 != 0.0) {
return (x4 * x3 <= 0.0)
|| ((x3 * x2 >= 0.0) && (x2 > 0.0 ? x3 <= x2 || x4 <= x2 : x3 >= x2
|| x4 >= x2));
}
if (y2 != 0.0) {
return (y4 * y3 <= 0.0)
|| ((y3 * y2 >= 0.0) && (y2 > 0.0 ? y3 <= y2 || y4 <= y2 : y3 >= y2
|| y4 >= y2));
}
return false;
}
double BvC = x3 * y4 - x4 * y3;
return (AvB * AvC <= 0.0) && (BvC * (AvB + BvC - AvC) <= 0.0);
}
/**
* Tells whether the specified line segments crosses this line segment.
*
* @param x1
* the x coordinate of the starting point of the test segment.
* @param y1
* the y coordinate of the starting point of the test segment.
* @param x2
* the x coordinate of the end point of the test segment.
* @param y2
* the y coordinate of the end point of the test segment.
* @return true, if the specified line segments crosses this line segment.
*/
public boolean intersectsLine(double x1, double y1, double x2, double y2) {
return linesIntersect(x1, y1, x2, y2, getX1(), getY1(), getX2(), getY2());
}
/**
* Tells whether the specified line segments crosses this line segment.
*
* @param l
* the test segment.
* @return true, if the specified line segments crosses this line segment.
* @throws NullPointerException
* if l is null.
*/
public boolean intersectsLine(Line2D l) {
return linesIntersect(l.getX1(), l.getY1(), l.getX2(), l.getY2(), getX1(), getY1(),
getX2(), getY2());
}
/**
* Gives the square of the distance between the point and the line segment.
*
* @param x1
* the x coordinate of the starting point of the line segment.
* @param y1
* the y coordinate of the starting point of the line segment.
* @param x2
* the x coordinate of the end point of the line segment.
* @param y2
* the y coordinate of the end point of the line segment.
* @param px
* the x coordinate of the test point.
* @param py
* the y coordinate of the test point.
* @return the the square of the distance between the point and the line
* segment.
*/
public static double ptSegDistSq(double x1, double y1, double x2, double y2, double px,
double py) {
/*
* A = (x2 - x1, y2 - y1) P = (px - x1, py - y1)
*/
x2 -= x1; // A = (x2, y2)
y2 -= y1;
px -= x1; // P = (px, py)
py -= y1;
double dist;
if (px * x2 + py * y2 <= 0.0) { // P*A
dist = px * px + py * py;
} else {
px = x2 - px; // P = A - P = (x2 - px, y2 - py)
py = y2 - py;
if (px * x2 + py * y2 <= 0.0) { // P*A
dist = px * px + py * py;
} else {
dist = px * y2 - py * x2;
dist = dist * dist / (x2 * x2 + y2 * y2); // pxA/|A|
}
}
if (dist < 0) {
dist = 0;
}
return dist;
}
/**
* Gives the distance between the point and the line segment.
*
* @param x1
* the x coordinate of the starting point of the line segment.
* @param y1
* the y coordinate of the starting point of the line segment.
* @param x2
* the x coordinate of the end point of the line segment.
* @param y2
* the y coordinate of the end point of the line segment.
* @param px
* the x coordinate of the test point.
* @param py
* the y coordinate of the test point.
* @return the the distance between the point and the line segment.
*/
public static double ptSegDist(double x1, double y1, double x2, double y2, double px, double py) {
return Math.sqrt(ptSegDistSq(x1, y1, x2, y2, px, py));
}
/**
* Gives the square of the distance between the point and this line segment.
*
* @param px
* the x coordinate of the test point.
* @param py
* the y coordinate of the test point.
* @return the the square of the distance between the point and this line
* segment.
*/
public double ptSegDistSq(double px, double py) {
return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
}
/**
* Gives the square of the distance between the point and this line segment.
*
* @param p
* the test point.
* @return the square of the distance between the point and this line
* segment.
*/
public double ptSegDistSq(Point2D p) {
return ptSegDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
}
/**
* Gives the distance between the point and this line segment.
*
* @param px
* the x coordinate of the test point.
* @param py
* the y coordinate of the test point.
* @return the distance between the point and this line segment.
*/
public double ptSegDist(double px, double py) {
return ptSegDist(getX1(), getY1(), getX2(), getY2(), px, py);
}
/**
* Gives the distance between the point and this line segment.
*
* @param p
* the test point.
* @return the distance between the point and this line segment.
*/
public double ptSegDist(Point2D p) {
return ptSegDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
}
/**
* Gives the square of the distance between the point and the line.
*
* @param x1
* the x coordinate of the starting point of the line segment.
* @param y1
* the y coordinate of the starting point of the line segment.
* @param x2
* the x coordinate of the end point of the line segment.
* @param y2
* the y coordinate of the end point of the line segment.
* @param px
* the x coordinate of the test point.
* @param py
* the y coordinate of the test point.
* @return the square of the distance between the point and the line.
*/
public static double ptLineDistSq(double x1, double y1, double x2, double y2, double px,
double py) {
x2 -= x1;
y2 -= y1;
px -= x1;
py -= y1;
double s = px * y2 - py * x2;
return s * s / (x2 * x2 + y2 * y2);
}
/**
* Gives the square of the distance between the point and the line.
*
* @param x1
* the x coordinate of the starting point of the line segment.
* @param y1
* the y coordinate of the starting point of the line segment.
* @param x2
* the x coordinate of the end point of the line segment.
* @param y2
* the y coordinate of the end point of the line segment.
* @param px
* the x coordinate of the test point.
* @param py
* the y coordinate of the test point.
* @return the square of the distance between the point and the line.
*/
public static double ptLineDist(double x1, double y1, double x2, double y2, double px, double py) {
return Math.sqrt(ptLineDistSq(x1, y1, x2, y2, px, py));
}
/**
* Gives the square of the distance between the point and the line
* determined by this Line2D.
*
* @param px
* the x coordinate of the test point.
* @param py
* the y coordinate of the test point.
* @return the square of the distance between the point and the line
* determined by this Line2D.
*/
public double ptLineDistSq(double px, double py) {
return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), px, py);
}
/**
* Gives the square of the distance between the point and the line
* determined by this Line2D.
*
* @param p
* the test point.
* @return the square of the distance between the point and the line
* determined by this Line2D.
*/
public double ptLineDistSq(Point2D p) {
return ptLineDistSq(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
}
/**
* Gives the distance between the point and the line determined by this
* Line2D.
*
* @param px
* the x coordinate of the test point.
* @param py
* the y coordinate of the test point.
* @return the distance between the point and the line determined by this
* Line2D.
*/
public double ptLineDist(double px, double py) {
return ptLineDist(getX1(), getY1(), getX2(), getY2(), px, py);
}
/**
* Gives the distance between the point and the line determined by this
* Line2D.
*
* @param p
* the test point.
* @return the distance between the point and the line determined by this
* Line2D.
*/
public double ptLineDist(Point2D p) {
return ptLineDist(getX1(), getY1(), getX2(), getY2(), p.getX(), p.getY());
}
public boolean contains(double px, double py) {
return false;
}
public boolean contains(Point2D p) {
return false;
}
public boolean contains(Rectangle2D r) {
return false;
}
public boolean contains(double rx, double ry, double rw, double rh) {
return false;
}
public boolean intersects(double rx, double ry, double rw, double rh) {
return intersects(new Rectangle2D.Double(rx, ry, rw, rh));
}
public boolean intersects(Rectangle2D r) {
return r.intersectsLine(getX1(), getY1(), getX2(), getY2());
}
public PathIterator getPathIterator(AffineTransform at) {
return new Iterator(this, at);
}
public PathIterator getPathIterator(AffineTransform at, double flatness) {
return new Iterator(this, at);
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
}
@@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
/**
* The Class NoninvertibleTransformException is the exception that is thrown
* when an action requires inverting an {@link AffineTransform} that is not
* invertible (has determinant 0).
*
* @since Android 1.0
*/
public class NoninvertibleTransformException extends java.lang.Exception {
/**
* The Constant serialVersionUID.
*/
private static final long serialVersionUID = 6137225240503990466L;
/**
* Instantiates a new non-invertible transform exception.
*
* @param s
* the error message.
*/
public NoninvertibleTransformException(String s) {
super(s);
}
}
@@ -0,0 +1,146 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
/**
* The Interface PathIterator represents an iterator object that can be used to
* traverse the outline of a {@link java.awt.Shape}. It returns points along the
* boundary of the Shape which may be actual vertices (in the case of a shape
* made of line segments) or may be points on a curved segment with the distance
* between the points determined by a chosen flattening factor.
* <p>
* If the shape is closed, the outline is traversed in the counter-clockwise
* direction. That means that moving forward along the boundary is to travel in
* such a way that the interior of the shape is to the left of the outline path
* and the exterior of the shape is to the right of the outline path. The
* interior and exterior of the shape are determined by a winding rule.
* </p>
*
* @since Android 1.0
*/
public interface PathIterator {
/**
* The Constant WIND_EVEN_ODD indicates the winding rule that says that a
* point is outside the shape if any infinite ray from the point crosses the
* outline of the shape an even number of times, otherwise it is inside.
*/
public static final int WIND_EVEN_ODD = 0;
/**
* The Constant WIND_NON_ZERO indicates the winding rule that says that a
* point is inside the shape if every infinite ray starting from that point
* crosses the outline of the shape a non-zero number of times.
*/
public static final int WIND_NON_ZERO = 1;
/**
* The Constant SEG_MOVETO indicates that to follow the shape's outline from
* the previous point to the current point, the cursor (traversal point)
* should be placed directly on the current point.
*/
public static final int SEG_MOVETO = 0;
/**
* The Constant SEG_LINETO indicates that to follow the shape's outline from
* the previous point to the current point, the cursor (traversal point)
* should follow a straight line.
*/
public static final int SEG_LINETO = 1;
/**
* The Constant SEG_QUADTO indicates that to follow the shape's outline from
* the previous point to the current point, the cursor (traversal point)
* should follow a quadratic curve.
*/
public static final int SEG_QUADTO = 2;
/**
* The Constant SEG_CUBICTO indicates that to follow the shape's outline
* from the previous point to the current point, the cursor (traversal
* point) should follow a cubic curve.
*/
public static final int SEG_CUBICTO = 3;
/**
* The Constant SEG_CLOSE indicates that the previous point was the end of
* the shape's outline.
*/
public static final int SEG_CLOSE = 4;
/**
* Gets the winding rule, either {@link PathIterator#WIND_EVEN_ODD} or
* {@link PathIterator#WIND_NON_ZERO}.
*
* @return the winding rule.
*/
public int getWindingRule();
/**
* Checks if this PathIterator has been completely traversed.
*
* @return true, if this PathIterator has been completely traversed.
*/
public boolean isDone();
/**
* Tells this PathIterator to skip to the next segment.
*/
public void next();
/**
* Gets the coordinates of the next vertex point along the shape's outline
* and a flag that indicates what kind of segment to use in order to connect
* the previous vertex point to the current vertex point to form the current
* segment.
*
* @param coords
* the array that the coordinates of the end point of the current
* segment are written into.
* @return the flag that indicates how to follow the shape's outline from
* the previous point to the current one, chosen from the following
* constants: {@link PathIterator#SEG_MOVETO},
* {@link PathIterator#SEG_LINETO}, {@link PathIterator#SEG_QUADTO},
* {@link PathIterator#SEG_CUBICTO}, or
* {@link PathIterator#SEG_CLOSE}.
*/
public int currentSegment(float[] coords);
/**
* Gets the coordinates of the next vertex point along the shape's outline
* and a flag that indicates what kind of segment to use in order to connect
* the previous vertex point to the current vertex point to form the current
* segment.
*
* @param coords
* the array that the coordinates of the end point of the current
* segment are written into.
* @return the flag that indicates how to follow the shape's outline from
* the previous point to the current one, chosen from the following
* constants: {@link PathIterator#SEG_MOVETO},
* {@link PathIterator#SEG_LINETO}, {@link PathIterator#SEG_QUADTO},
* {@link PathIterator#SEG_CUBICTO}, or
* {@link PathIterator#SEG_CLOSE}.
*/
public int currentSegment(double[] coords);
}
@@ -0,0 +1,323 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
import org.apache.harmony.misc.HashCode;
/**
* The Class Point2D represents a point whose data is given in high-precision
* values appropriate for graphical operations.
*
* @since Android 1.0
*/
public abstract class Point2D implements Cloneable {
/**
* The Class Float is the subclass of Point2D that has all of its data
* values stored with float-level precision.
*
* @since Android 1.0
*/
public static class Float extends Point2D {
/**
* The x coordinate.
*/
public float x;
/**
* The y coordinate.
*/
public float y;
/**
* Instantiates a new float-valued Point2D with its data set to zero.
*/
public Float() {
}
/**
* Instantiates a new float-valued Point2D with the specified
* coordinates.
*
* @param x
* the x coordinate.
* @param y
* the y coordinate.
*/
public Float(float x, float y) {
this.x = x;
this.y = y;
}
@Override
public double getX() {
return x;
}
@Override
public double getY() {
return y;
}
/**
* Sets the point's coordinates.
*
* @param x
* the x coordinate.
* @param y
* the y coordinate.
*/
public void setLocation(float x, float y) {
this.x = x;
this.y = y;
}
@Override
public void setLocation(double x, double y) {
this.x = (float)x;
this.y = (float)y;
}
@Override
public String toString() {
return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
/**
* The Class Double is the subclass of Point2D that has all of its data
* values stored with double-level precision.
*
* @since Android 1.0
*/
public static class Double extends Point2D {
/**
* The x coordinate.
*/
public double x;
/**
* The y coordinate.
*/
public double y;
/**
* Instantiates a new double-valued Point2D with its data set to zero.
*/
public Double() {
}
/**
* Instantiates a new double-valued Point2D with the specified
* coordinates.
*
* @param x
* the x coordinate.
* @param y
* the y coordinate.
*/
public Double(double x, double y) {
this.x = x;
this.y = y;
}
@Override
public double getX() {
return x;
}
@Override
public double getY() {
return y;
}
@Override
public void setLocation(double x, double y) {
this.x = x;
this.y = y;
}
@Override
public String toString() {
return getClass().getName() + "[x=" + x + ",y=" + y + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
}
/**
* Instantiates a new Point2D.
*/
protected Point2D() {
}
/**
* Gets the x coordinate.
*
* @return the x coordinate.
*/
public abstract double getX();
/**
* Gets the y coordinate.
*
* @return the y coordinate.
*/
public abstract double getY();
/**
* Sets the point's coordinates.
*
* @param x
* the x coordinate.
* @param y
* the y coordinate.
*/
public abstract void setLocation(double x, double y);
/**
* Sets the point's coordinates by copying them from another point.
*
* @param p
* the point to copy the data from.
*/
public void setLocation(Point2D p) {
setLocation(p.getX(), p.getY());
}
/**
* Finds the square of the distance between the two specified points.
*
* @param x1
* the x coordinate of the first point.
* @param y1
* the y coordinate of the first point.
* @param x2
* the x coordinate of the second point.
* @param y2
* the y coordinate of the second point.
* @return the square of the distance between the two specified points.
*/
public static double distanceSq(double x1, double y1, double x2, double y2) {
x2 -= x1;
y2 -= y1;
return x2 * x2 + y2 * y2;
}
/**
* Finds the square of the distance between this point and the specified
* point.
*
* @param px
* the x coordinate of the point.
* @param py
* the y coordinate of the point.
* @return the square of the distance between this point and the specified
* point.
*/
public double distanceSq(double px, double py) {
return Point2D.distanceSq(getX(), getY(), px, py);
}
/**
* Finds the square of the distance between this point and the specified
* point.
*
* @param p
* the other point.
* @return the square of the distance between this point and the specified
* point.
*/
public double distanceSq(Point2D p) {
return Point2D.distanceSq(getX(), getY(), p.getX(), p.getY());
}
/**
* Finds the distance between the two specified points.
*
* @param x1
* the x coordinate of the first point.
* @param y1
* the y coordinate of the first point.
* @param x2
* the x coordinate of the second point.
* @param y2
* the y coordinate of the second point.
* @return the distance between the two specified points.
*/
public static double distance(double x1, double y1, double x2, double y2) {
return Math.sqrt(distanceSq(x1, y1, x2, y2));
}
/**
* Finds the distance between this point and the specified point.
*
* @param px
* the x coordinate of the point.
* @param py
* the y coordinate of the point.
* @return the distance between this point and the specified point.
*/
public double distance(double px, double py) {
return Math.sqrt(distanceSq(px, py));
}
/**
* Finds the distance between this point and the specified point.
*
* @param p
* the other point.
* @return the distance between this point and the specified point.
*/
public double distance(Point2D p) {
return Math.sqrt(distanceSq(p));
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
@Override
public int hashCode() {
HashCode hash = new HashCode();
hash.append(getX());
hash.append(getY());
return hash.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Point2D) {
Point2D p = (Point2D)obj;
return getX() == p.getX() && getY() == p.getY();
}
return false;
}
}
@@ -0,0 +1,918 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
import java.awt.Rectangle;
import java.awt.Shape;
import java.util.NoSuchElementException;
import org.apache.harmony.awt.gl.Crossing;
import org.apache.harmony.awt.internal.nls.Messages;
/**
* The Class QuadCurve2D is a Shape that represents a segment of a quadratic
* (Bezier) curve. The curved segment is determined by three points: a start
* point, an end point, and a control point. The line from the control point to
* the starting point gives the tangent to the curve at the starting point, and
* the line from the control point to the end point gives the tangent to the
* curve at the end point.
*
* @since Android 1.0
*/
public abstract class QuadCurve2D implements Shape, Cloneable {
/**
* The Class Float is the subclass of QuadCurve2D that has all of its data
* values stored with float-level precision.
*
* @since Android 1.0
*/
public static class Float extends QuadCurve2D {
/**
* The x coordinate of the starting point of the curved segment.
*/
public float x1;
/**
* The y coordinate of the starting point of the curved segment.
*/
public float y1;
/**
* The x coordinate of the control point.
*/
public float ctrlx;
/**
* The y coordinate of the control point.
*/
public float ctrly;
/**
* The x coordinate of the end point of the curved segment.
*/
public float x2;
/**
* The y coordinate of the end point of the curved segment.
*/
public float y2;
/**
* Instantiates a new float-valued QuadCurve2D with all coordinate
* values set to zero.
*/
public Float() {
}
/**
* Instantiates a new float-valued QuadCurve2D with the specified
* coordinate values.
*
* @param x1
* the x coordinate of the starting point of the curved
* segment.
* @param y1
* the y coordinate of the starting point of the curved
* segment.
* @param ctrlx
* the x coordinate of the control point.
* @param ctrly
* the y coordinate of the control point.
* @param x2
* the x coordinate of the end point of the curved segment.
* @param y2
* the y coordinate of the end point of the curved segment.
*/
public Float(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
setCurve(x1, y1, ctrlx, ctrly, x2, y2);
}
@Override
public double getX1() {
return x1;
}
@Override
public double getY1() {
return y1;
}
@Override
public double getCtrlX() {
return ctrlx;
}
@Override
public double getCtrlY() {
return ctrly;
}
@Override
public double getX2() {
return x2;
}
@Override
public double getY2() {
return y2;
}
@Override
public Point2D getP1() {
return new Point2D.Float(x1, y1);
}
@Override
public Point2D getCtrlPt() {
return new Point2D.Float(ctrlx, ctrly);
}
@Override
public Point2D getP2() {
return new Point2D.Float(x2, y2);
}
@Override
public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
this.x1 = (float)x1;
this.y1 = (float)y1;
this.ctrlx = (float)ctrlx;
this.ctrly = (float)ctrly;
this.x2 = (float)x2;
this.y2 = (float)y2;
}
/**
* Sets the data values of the curve.
*
* @param x1
* the x coordinate of the starting point of the curved
* segment.
* @param y1
* the y coordinate of the starting point of the curved
* segment.
* @param ctrlx
* the x coordinate of the control point.
* @param ctrly
* the y coordinate of the control point.
* @param x2
* the x coordinate of the end point of the curved segment.
* @param y2
* the y coordinate of the end point of the curved segment.
*/
public void setCurve(float x1, float y1, float ctrlx, float ctrly, float x2, float y2) {
this.x1 = x1;
this.y1 = y1;
this.ctrlx = ctrlx;
this.ctrly = ctrly;
this.x2 = x2;
this.y2 = y2;
}
public Rectangle2D getBounds2D() {
float rx0 = Math.min(Math.min(x1, x2), ctrlx);
float ry0 = Math.min(Math.min(y1, y2), ctrly);
float rx1 = Math.max(Math.max(x1, x2), ctrlx);
float ry1 = Math.max(Math.max(y1, y2), ctrly);
return new Rectangle2D.Float(rx0, ry0, rx1 - rx0, ry1 - ry0);
}
}
/**
* The Class Double is the subclass of QuadCurve2D that has all of its data
* values stored with double-level precision.
*
* @since Android 1.0
*/
public static class Double extends QuadCurve2D {
/**
* The x coordinate of the starting point of the curved segment.
*/
public double x1;
/**
* The y coordinate of the starting point of the curved segment.
*/
public double y1;
/**
* The x coordinate of the control point.
*/
public double ctrlx;
/**
* The y coordinate of the control point.
*/
public double ctrly;
/**
* The x coordinate of the end point of the curved segment.
*/
public double x2;
/**
* The y coordinate of the end point of the curved segment.
*/
public double y2;
/**
* Instantiates a new double-valued QuadCurve2D with all coordinate
* values set to zero.
*/
public Double() {
}
/**
* Instantiates a new double-valued QuadCurve2D with the specified
* coordinate values.
*
* @param x1
* the x coordinate of the starting point of the curved
* segment.
* @param y1
* the y coordinate of the starting point of the curved
* segment.
* @param ctrlx
* the x coordinate of the control point.
* @param ctrly
* the y coordinate of the control point.
* @param x2
* the x coordinate of the end point of the curved segment.
* @param y2
* the y coordinate of the end point of the curved segment.
*/
public Double(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
setCurve(x1, y1, ctrlx, ctrly, x2, y2);
}
@Override
public double getX1() {
return x1;
}
@Override
public double getY1() {
return y1;
}
@Override
public double getCtrlX() {
return ctrlx;
}
@Override
public double getCtrlY() {
return ctrly;
}
@Override
public double getX2() {
return x2;
}
@Override
public double getY2() {
return y2;
}
@Override
public Point2D getP1() {
return new Point2D.Double(x1, y1);
}
@Override
public Point2D getCtrlPt() {
return new Point2D.Double(ctrlx, ctrly);
}
@Override
public Point2D getP2() {
return new Point2D.Double(x2, y2);
}
@Override
public void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2, double y2) {
this.x1 = x1;
this.y1 = y1;
this.ctrlx = ctrlx;
this.ctrly = ctrly;
this.x2 = x2;
this.y2 = y2;
}
public Rectangle2D getBounds2D() {
double rx0 = Math.min(Math.min(x1, x2), ctrlx);
double ry0 = Math.min(Math.min(y1, y2), ctrly);
double rx1 = Math.max(Math.max(x1, x2), ctrlx);
double ry1 = Math.max(Math.max(y1, y2), ctrly);
return new Rectangle2D.Double(rx0, ry0, rx1 - rx0, ry1 - ry0);
}
}
/*
* QuadCurve2D path iterator
*/
/**
* The PathIterator for a Quad2D curve.
*/
class Iterator implements PathIterator {
/**
* The source QuadCurve2D object.
*/
QuadCurve2D c;
/**
* The path iterator transformation.
*/
AffineTransform t;
/**
* The current segment index.
*/
int index;
/**
* Constructs a new QuadCurve2D.Iterator for given curve and
* transformation
*
* @param q
* the source QuadCurve2D object.
* @param t
* the AffineTransform that acts on the coordinates before
* returning them (or null).
*/
Iterator(QuadCurve2D q, AffineTransform t) {
this.c = q;
this.t = t;
}
public int getWindingRule() {
return WIND_NON_ZERO;
}
public boolean isDone() {
return (index > 1);
}
public void next() {
index++;
}
public int currentSegment(double[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
int type;
int count;
if (index == 0) {
type = SEG_MOVETO;
coords[0] = c.getX1();
coords[1] = c.getY1();
count = 1;
} else {
type = SEG_QUADTO;
coords[0] = c.getCtrlX();
coords[1] = c.getCtrlY();
coords[2] = c.getX2();
coords[3] = c.getY2();
count = 2;
}
if (t != null) {
t.transform(coords, 0, coords, 0, count);
}
return type;
}
public int currentSegment(float[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
int type;
int count;
if (index == 0) {
type = SEG_MOVETO;
coords[0] = (float)c.getX1();
coords[1] = (float)c.getY1();
count = 1;
} else {
type = SEG_QUADTO;
coords[0] = (float)c.getCtrlX();
coords[1] = (float)c.getCtrlY();
coords[2] = (float)c.getX2();
coords[3] = (float)c.getY2();
count = 2;
}
if (t != null) {
t.transform(coords, 0, coords, 0, count);
}
return type;
}
}
/**
* Instantiates a new quadratic curve.
*/
protected QuadCurve2D() {
}
/**
* Gets the x coordinate of the starting point.
*
* @return the x coordinate of the starting point.
*/
public abstract double getX1();
/**
* Gets the y coordinate of the starting point.
*
* @return the y coordinate of the starting point.
*/
public abstract double getY1();
/**
* Gets the starting point.
*
* @return the starting point.
*/
public abstract Point2D getP1();
/**
* Gets the x coordinate of the control point.
*
* @return the x coordinate of the control point.
*/
public abstract double getCtrlX();
/**
* Gets the y coordinate of the control point.
*
* @return y coordinate of the control point.
*/
public abstract double getCtrlY();
/**
* Gets the control point.
*
* @return the control point.
*/
public abstract Point2D getCtrlPt();
/**
* Gets the x coordinate of the end point.
*
* @return the x coordinate of the end point.
*/
public abstract double getX2();
/**
* Gets the y coordinate of the end point.
*
* @return the y coordinate of the end point.
*/
public abstract double getY2();
/**
* Gets the end point.
*
* @return the end point.
*/
public abstract Point2D getP2();
/**
* Sets the data of the curve.
*
* @param x1
* the x coordinate of the starting point of the curved segment.
* @param y1
* the y coordinate of the starting point of the curved segment.
* @param ctrlx
* the x coordinate of the control point.
* @param ctrly
* the y coordinate of the control point.
* @param x2
* the x coordinate of the end point of the curved segment.
* @param y2
* the y coordinate of the end point of the curved segment.
*/
public abstract void setCurve(double x1, double y1, double ctrlx, double ctrly, double x2,
double y2);
/**
* Sets the data of the curve.
*
* @param p1
* the starting point of the curved segment.
* @param cp
* the control point.
* @param p2
* the end point of the curved segment.
* @throws NullPointerException
* if any of the three points is null.
*/
public void setCurve(Point2D p1, Point2D cp, Point2D p2) {
setCurve(p1.getX(), p1.getY(), cp.getX(), cp.getY(), p2.getX(), p2.getY());
}
/**
* Sets the data of the curve by reading the data from an array of values.
* The values are read in the same order as the arguments of the method
* {@link QuadCurve2D#setCurve(double, double, double, double, double, double)}
* .
*
* @param coords
* the array of values containing the new coordinates.
* @param offset
* the offset of the data to read within the array.
* @throws ArrayIndexOutOfBoundsException
* if {@code coords.length} < offset + 6.
* @throws NullPointerException
* if the coordinate array is null.
*/
public void setCurve(double[] coords, int offset) {
setCurve(coords[offset + 0], coords[offset + 1], coords[offset + 2], coords[offset + 3],
coords[offset + 4], coords[offset + 5]);
}
/**
* Sets the data of the curve by reading the data from an array of points.
* The values are read in the same order as the arguments of the method
* {@link QuadCurve2D#setCurve(Point2D, Point2D, Point2D)}.
*
* @param points
* the array of points containing the new coordinates.
* @param offset
* the offset of the data to read within the array.
* @throws ArrayIndexOutOfBoundsException
* if points.length < offset + 3.
* @throws NullPointerException
* if the point array is null.
*/
public void setCurve(Point2D[] points, int offset) {
setCurve(points[offset + 0].getX(), points[offset + 0].getY(), points[offset + 1].getX(),
points[offset + 1].getY(), points[offset + 2].getX(), points[offset + 2].getY());
}
/**
* Sets the data of the curve by copying it from another QuadCurve2D.
*
* @param curve
* the curve to copy the data points from.
* @throws NullPointerException
* if the curve is null.
*/
public void setCurve(QuadCurve2D curve) {
setCurve(curve.getX1(), curve.getY1(), curve.getCtrlX(), curve.getCtrlY(), curve.getX2(),
curve.getY2());
}
/**
* Gets the square of the distance from the control point to the straight
* line segment connecting the start point and the end point for this curve.
*
* @return the square of the distance from the control point to the straight
* line segment connecting the start point and the end point.
*/
public double getFlatnessSq() {
return Line2D.ptSegDistSq(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY());
}
/**
* Gets the square of the distance from the control point to the straight
* line segment connecting the start point and the end point.
*
* @param x1
* the x coordinate of the starting point of the curved segment.
* @param y1
* the y coordinate of the starting point of the curved segment.
* @param ctrlx
* the x coordinate of the control point.
* @param ctrly
* the y coordinate of the control point.
* @param x2
* the x coordinate of the end point of the curved segment.
* @param y2
* the y coordinate of the end point of the curved segment.
* @return the square of the distance from the control point to the straight
* line segment connecting the start point and the end point.
*/
public static double getFlatnessSq(double x1, double y1, double ctrlx, double ctrly, double x2,
double y2) {
return Line2D.ptSegDistSq(x1, y1, x2, y2, ctrlx, ctrly);
}
/**
* Gets the square of the distance from the control point to the straight
* line segment connecting the start point and the end point by reading the
* coordinates of the points from an array of values. The values are read in
* the same order as the arguments of the method
* {@link QuadCurve2D#getFlatnessSq(double, double, double, double, double, double)}
* .
*
* @param coords
* the array of points containing the coordinates to use for the
* calculation
* @param offset
* the offset of the data to read within the array
* @return the square of the distance from the control point to the straight
* line segment connecting the start point and the end point.
* @throws ArrayIndexOutOfBoundsException
* if {@code coords.length} < offset + 6.
* @throws NullPointerException
* if the coordinate array is null.
*/
public static double getFlatnessSq(double coords[], int offset) {
return Line2D.ptSegDistSq(coords[offset + 0], coords[offset + 1], coords[offset + 4],
coords[offset + 5], coords[offset + 2], coords[offset + 3]);
}
/**
* Gets the distance from the control point to the straight line segment
* connecting the start point and the end point of this QuadCurve2D.
*
* @return the the distance from the control point to the straight line
* segment connecting the start point and the end point of this
* QuadCurve2D.
*/
public double getFlatness() {
return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(), getCtrlY());
}
/**
* Gets the distance from the control point to the straight line segment
* connecting the start point and the end point.
*
* @param x1
* the x coordinate of the starting point of the curved segment.
* @param y1
* the y coordinate of the starting point of the curved segment.
* @param ctrlx
* the x coordinate of the control point.
* @param ctrly
* the y coordinate of the control point.
* @param x2
* the x coordinate of the end point of the curved segment.
* @param y2
* the y coordinate of the end point of the curved segment.
* @return the the distance from the control point to the straight line
* segment connecting the start point and the end point.
*/
public static double getFlatness(double x1, double y1, double ctrlx, double ctrly, double x2,
double y2) {
return Line2D.ptSegDist(x1, y1, x2, y2, ctrlx, ctrly);
}
/**
* Gets the the distance from the control point to the straight line segment
* connecting the start point and the end point. The values are read in the
* same order as the arguments of the method
* {@link QuadCurve2D#getFlatness(double, double, double, double, double, double)}
* .
*
* @param coords
* the array of points containing the coordinates to use for the
* calculation.
* @param offset
* the offset of the data to read within the array.
* @return the the distance from the control point to the straight line
* segment connecting the start point and the end point.
* @throws ArrayIndexOutOfBoundsException
* if {code coords.length} < offset + 6.
* @throws NullPointerException
* if the coordinate array is null.
*/
public static double getFlatness(double coords[], int offset) {
return Line2D.ptSegDist(coords[offset + 0], coords[offset + 1], coords[offset + 4],
coords[offset + 5], coords[offset + 2], coords[offset + 3]);
}
/**
* Creates the data for two quadratic curves by dividing this curve in two.
* The division point is the point on the curve that is closest to this
* curve's control point. The data of this curve is left unchanged.
*
* @param left
* the QuadCurve2D where the left (start) segment's data is
* written.
* @param right
* the QuadCurve2D where the right (end) segment's data is
* written.
* @throws NullPointerException
* if either curve is null.
*/
public void subdivide(QuadCurve2D left, QuadCurve2D right) {
subdivide(this, left, right);
}
/**
* Creates the data for two quadratic curves by dividing a source curve in
* two. The division point is the point on the curve that is closest to the
* source curve's control point. The data of the source curve is left
* unchanged.
*
* @param src
* the curve that provides the initial data.
* @param left
* the QuadCurve2D where the left (start) segment's data is
* written.
* @param right
* the QuadCurve2D where the right (end) segment's data is
* written.
* @throws NullPointerException
* if one of the curves is null.
*/
public static void subdivide(QuadCurve2D src, QuadCurve2D left, QuadCurve2D right) {
double x1 = src.getX1();
double y1 = src.getY1();
double cx = src.getCtrlX();
double cy = src.getCtrlY();
double x2 = src.getX2();
double y2 = src.getY2();
double cx1 = (x1 + cx) / 2.0;
double cy1 = (y1 + cy) / 2.0;
double cx2 = (x2 + cx) / 2.0;
double cy2 = (y2 + cy) / 2.0;
cx = (cx1 + cx2) / 2.0;
cy = (cy1 + cy2) / 2.0;
if (left != null) {
left.setCurve(x1, y1, cx1, cy1, cx, cy);
}
if (right != null) {
right.setCurve(cx, cy, cx2, cy2, x2, y2);
}
}
/**
* Creates the data for two quadratic curves by dividing a source curve in
* two. The division point is the point on the curve that is closest to the
* source curve's control point. The data for the three curves is read and
* written from arrays of values in the usual order: x1, y1, cx, cy, x2, y2.
*
* @param src
* the array that gives the data values for the source curve.
* @param srcoff
* the offset in the src array to read the values from.
* @param left
* the array where the coordinates of the start curve should be
* written.
* @param leftOff
* the offset in the left array to start writing the values.
* @param right
* the array where the coordinates of the end curve should be
* written.
* @param rightOff
* the offset in the right array to start writing the values.
* @throws ArrayIndexOutOfBoundsException
* if {@code src.length} < srcoff + 6 or if {@code left.length}
* < leftOff + 6 or if {@code right.length} < rightOff + 6.
* @throws NullPointerException
* if one of the arrays is null.
*/
public static void subdivide(double src[], int srcoff, double left[], int leftOff,
double right[], int rightOff) {
double x1 = src[srcoff + 0];
double y1 = src[srcoff + 1];
double cx = src[srcoff + 2];
double cy = src[srcoff + 3];
double x2 = src[srcoff + 4];
double y2 = src[srcoff + 5];
double cx1 = (x1 + cx) / 2.0;
double cy1 = (y1 + cy) / 2.0;
double cx2 = (x2 + cx) / 2.0;
double cy2 = (y2 + cy) / 2.0;
cx = (cx1 + cx2) / 2.0;
cy = (cy1 + cy2) / 2.0;
if (left != null) {
left[leftOff + 0] = x1;
left[leftOff + 1] = y1;
left[leftOff + 2] = cx1;
left[leftOff + 3] = cy1;
left[leftOff + 4] = cx;
left[leftOff + 5] = cy;
}
if (right != null) {
right[rightOff + 0] = cx;
right[rightOff + 1] = cy;
right[rightOff + 2] = cx2;
right[rightOff + 3] = cy2;
right[rightOff + 4] = x2;
right[rightOff + 5] = y2;
}
}
/**
* Finds the roots of the quadratic polynomial. This is accomplished by
* finding the (real) values of x that solve the following equation:
* eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written back into
* the array eqn starting from the index 0 in the array. The return value
* tells how many array elements have been changed by this method call.
*
* @param eqn
* an array containing the coefficients of the quadratic
* polynomial to solve.
* @return the number of roots of the quadratic polynomial.
* @throws ArrayIndexOutOfBoundsException
* if {@code eqn.length} < 3.
* @throws NullPointerException
* if the array is null.
*/
public static int solveQuadratic(double eqn[]) {
return solveQuadratic(eqn, eqn);
}
/**
* Finds the roots of the quadratic polynomial. This is accomplished by
* finding the (real) values of x that solve the following equation:
* eqn[2]*x*x + eqn[1]*x + eqn[0] = 0. The solutions are written into the
* array res starting from the index 0 in the array. The return value tells
* how many array elements have been written by this method call.
*
* @param eqn
* an array containing the coefficients of the quadratic
* polynomial to solve.
* @param res
* the array that this method writes the results into.
* @return the number of roots of the quadratic polynomial.
* @throws ArrayIndexOutOfBoundsException
* if {@code eqn.length} < 3 or if {@code res.length} is less
* than the number of roots.
* @throws NullPointerException
* if either array is null.
*/
public static int solveQuadratic(double eqn[], double res[]) {
return Crossing.solveQuad(eqn, res);
}
public boolean contains(double px, double py) {
return Crossing.isInsideEvenOdd(Crossing.crossShape(this, px, py));
}
public boolean contains(double rx, double ry, double rw, double rh) {
int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
return cross != Crossing.CROSSING && Crossing.isInsideEvenOdd(cross);
}
public boolean intersects(double rx, double ry, double rw, double rh) {
int cross = Crossing.intersectShape(this, rx, ry, rw, rh);
return cross == Crossing.CROSSING || Crossing.isInsideEvenOdd(cross);
}
public boolean contains(Point2D p) {
return contains(p.getX(), p.getY());
}
public boolean intersects(Rectangle2D r) {
return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
public boolean contains(Rectangle2D r) {
return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
public Rectangle getBounds() {
return getBounds2D().getBounds();
}
public PathIterator getPathIterator(AffineTransform t) {
return new Iterator(this, t);
}
public PathIterator getPathIterator(AffineTransform t, double flatness) {
return new FlatteningPathIterator(getPathIterator(t), flatness);
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
}
@@ -0,0 +1,824 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
import java.util.NoSuchElementException;
import org.apache.harmony.awt.internal.nls.Messages;
import org.apache.harmony.misc.HashCode;
/**
* The Class Rectangle2D represents a rectangle whose coordinates are given with
* the correct precision to be used with the Graphics2D classes.
*
* @since Android 1.0
*/
public abstract class Rectangle2D extends RectangularShape {
/**
* The Constant OUT_LEFT is a mask that is used to indicate that a given
* point is outside the rectangle and to its left.
*/
public static final int OUT_LEFT = 1;
/**
* The Constant OUT_TOP is a mask that is used to indicate that a given
* point is outside the rectangle and above it.
*/
public static final int OUT_TOP = 2;
/**
* The Constant OUT_RIGHT is a mask that is used to indicate that a given
* point is outside the rectangle and to its right.
*/
public static final int OUT_RIGHT = 4;
/**
* The Constant OUT_BOTTOM is a mask that is used to indicate that a given
* point is outside the rectangle and above it.
*/
public static final int OUT_BOTTOM = 8;
/**
* The Class Float is the subclass of Rectangle2D that represents a
* rectangle whose data values are given as floats (with float-level
* precision).
*
* @since Android 1.0
*/
public static class Float extends Rectangle2D {
/**
* The x coordinate of the rectangle's upper left corner.
*/
public float x;
/**
* The y coordinate of the rectangle's upper left corner.
*/
public float y;
/**
* The width of the rectangle.
*/
public float width;
/**
* The height of the rectangle.
*/
public float height;
/**
* Instantiates a new empty rectangle with float-precision data fields.
*/
public Float() {
}
/**
* Instantiates a new rectangle with the specified float-precision data.
*
* @param x
* the x coordinate of the rectangle's upper left corner.
* @param y
* the y coordinate of the rectangle's upper left corner.
* @param width
* the width of the rectangle.
* @param height
* the height of the rectangle.
*/
public Float(float x, float y, float width, float height) {
setRect(x, y, width, height);
}
@Override
public double getX() {
return x;
}
@Override
public double getY() {
return y;
}
@Override
public double getWidth() {
return width;
}
@Override
public double getHeight() {
return height;
}
@Override
public boolean isEmpty() {
return width <= 0.0f || height <= 0.0f;
}
/**
* Sets the rectangle's data to the given values.
*
* @param x
* the x coordinate of the rectangle's upper left corner.
* @param y
* the y coordinate of the rectangle's upper left corner.
* @param width
* the width of the rectangle.
* @param height
* the height of the rectangle.
*/
public void setRect(float x, float y, float width, float height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
@Override
public void setRect(double x, double y, double width, double height) {
this.x = (float)x;
this.y = (float)y;
this.width = (float)width;
this.height = (float)height;
}
@Override
public void setRect(Rectangle2D r) {
this.x = (float)r.getX();
this.y = (float)r.getY();
this.width = (float)r.getWidth();
this.height = (float)r.getHeight();
}
@Override
public int outcode(double px, double py) {
int code = 0;
if (width <= 0.0f) {
code |= OUT_LEFT | OUT_RIGHT;
} else if (px < x) {
code |= OUT_LEFT;
} else if (px > x + width) {
code |= OUT_RIGHT;
}
if (height <= 0.0f) {
code |= OUT_TOP | OUT_BOTTOM;
} else if (py < y) {
code |= OUT_TOP;
} else if (py > y + height) {
code |= OUT_BOTTOM;
}
return code;
}
@Override
public Rectangle2D getBounds2D() {
return new Float(x, y, width, height);
}
@Override
public Rectangle2D createIntersection(Rectangle2D r) {
Rectangle2D dst;
if (r instanceof Double) {
dst = new Rectangle2D.Double();
} else {
dst = new Rectangle2D.Float();
}
Rectangle2D.intersect(this, r, dst);
return dst;
}
@Override
public Rectangle2D createUnion(Rectangle2D r) {
Rectangle2D dst;
if (r instanceof Double) {
dst = new Rectangle2D.Double();
} else {
dst = new Rectangle2D.Float();
}
Rectangle2D.union(this, r, dst);
return dst;
}
@Override
public String toString() {
// The output format based on 1.5 release behaviour. It could be
// obtained in the following way
// System.out.println(new Rectangle2D.Float().toString())
return getClass().getName()
+ "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
}
}
/**
* The Class Double is the subclass of Rectangle2D that represents a
* rectangle whose data values are given as doubles (with
* double-precision-level precision).
*
* @since Android 1.0
*/
public static class Double extends Rectangle2D {
/**
* The x coordinate of the rectangle's upper left corner.
*/
public double x;
/**
* The y coordinate of the rectangle's upper left corner.
*/
public double y;
/**
* The width of the rectangle.
*/
public double width;
/**
* The height of the rectangle.
*/
public double height;
/**
* Instantiates a new empty rectangle with double-precision data fields.
*/
public Double() {
}
/**
* Instantiates a new rectangle with the given double values.
*
* @param x
* the x coordinate of the rectangle's upper left corner.
* @param y
* the y coordinate of the rectangle's upper left corner.
* @param width
* the width of the rectangle.
* @param height
* the height of the rectangle.
*/
public Double(double x, double y, double width, double height) {
setRect(x, y, width, height);
}
@Override
public double getX() {
return x;
}
@Override
public double getY() {
return y;
}
@Override
public double getWidth() {
return width;
}
@Override
public double getHeight() {
return height;
}
@Override
public boolean isEmpty() {
return width <= 0.0 || height <= 0.0;
}
@Override
public void setRect(double x, double y, double width, double height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
@Override
public void setRect(Rectangle2D r) {
this.x = r.getX();
this.y = r.getY();
this.width = r.getWidth();
this.height = r.getHeight();
}
@Override
public int outcode(double px, double py) {
int code = 0;
if (width <= 0.0) {
code |= OUT_LEFT | OUT_RIGHT;
} else if (px < x) {
code |= OUT_LEFT;
} else if (px > x + width) {
code |= OUT_RIGHT;
}
if (height <= 0.0) {
code |= OUT_TOP | OUT_BOTTOM;
} else if (py < y) {
code |= OUT_TOP;
} else if (py > y + height) {
code |= OUT_BOTTOM;
}
return code;
}
@Override
public Rectangle2D getBounds2D() {
return new Double(x, y, width, height);
}
@Override
public Rectangle2D createIntersection(Rectangle2D r) {
Rectangle2D dst = new Rectangle2D.Double();
Rectangle2D.intersect(this, r, dst);
return dst;
}
@Override
public Rectangle2D createUnion(Rectangle2D r) {
Rectangle2D dest = new Rectangle2D.Double();
Rectangle2D.union(this, r, dest);
return dest;
}
@Override
public String toString() {
// The output format based on 1.5 release behaviour. It could be
// obtained in the following way
// System.out.println(new Rectangle2D.Double().toString())
return getClass().getName()
+ "[x=" + x + ",y=" + y + ",width=" + width + ",height=" + height + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
}
}
/**
* The Class Iterator provides access to the coordinates of the
* Rectangle2D's boundary modified by an AffineTransform.
*/
class Iterator implements PathIterator {
/**
* The x coordinate of the rectangle's upper left corner.
*/
double x;
/**
* The y coordinate of the rectangle's upper left corner.
*/
double y;
/**
* The width of the rectangle.
*/
double width;
/**
* The height of the rectangle.
*/
double height;
/**
* The AffineTransform that is used to modify the coordinates that are
* returned by the path iterator.
*/
AffineTransform t;
/**
* The current segment index.
*/
int index;
/**
* Constructs a new Rectangle2D.Iterator for given rectangle and
* transformation.
*
* @param r
* the source Rectangle2D object.
* @param at
* the AffineTransform object to apply to the coordinates
* before returning them.
*/
Iterator(Rectangle2D r, AffineTransform at) {
this.x = r.getX();
this.y = r.getY();
this.width = r.getWidth();
this.height = r.getHeight();
this.t = at;
if (width < 0.0 || height < 0.0) {
index = 6;
}
}
public int getWindingRule() {
return WIND_NON_ZERO;
}
public boolean isDone() {
return index > 5;
}
public void next() {
index++;
}
public int currentSegment(double[] coords) {
if (isDone()) {
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
if (index == 5) {
return SEG_CLOSE;
}
int type;
if (index == 0) {
type = SEG_MOVETO;
coords[0] = x;
coords[1] = y;
} else {
type = SEG_LINETO;
switch (index) {
case 1:
coords[0] = x + width;
coords[1] = y;
break;
case 2:
coords[0] = x + width;
coords[1] = y + height;
break;
case 3:
coords[0] = x;
coords[1] = y + height;
break;
case 4:
coords[0] = x;
coords[1] = y;
break;
}
}
if (t != null) {
t.transform(coords, 0, coords, 0, 1);
}
return type;
}
public int currentSegment(float[] coords) {
if (isDone()) {
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
if (index == 5) {
return SEG_CLOSE;
}
int type;
if (index == 0) {
coords[0] = (float)x;
coords[1] = (float)y;
type = SEG_MOVETO;
} else {
type = SEG_LINETO;
switch (index) {
case 1:
coords[0] = (float)(x + width);
coords[1] = (float)y;
break;
case 2:
coords[0] = (float)(x + width);
coords[1] = (float)(y + height);
break;
case 3:
coords[0] = (float)x;
coords[1] = (float)(y + height);
break;
case 4:
coords[0] = (float)x;
coords[1] = (float)y;
break;
}
}
if (t != null) {
t.transform(coords, 0, coords, 0, 1);
}
return type;
}
}
/**
* Instantiates a new Rectangle2D.
*/
protected Rectangle2D() {
}
/**
* Sets the rectangle's location and dimension.
*
* @param x
* the x coordinate of the rectangle's upper left corner.
* @param y
* the y coordinate of the rectangle's upper left corner.
* @param width
* the width of the rectangle.
* @param height
* the height of the rectangle.
*/
public abstract void setRect(double x, double y, double width, double height);
/**
* Gets the location of the point with respect to the rectangle and packs
* the information into a single integer using the bitmasks
* {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT},
* {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}. If the
* rectangle has zero or negative width, then every point is regarded as
* being both to the left and to the right of the rectangle. Similarly, if
* the height is zero or negative then all points are considered to be both
* both above and below it.
*
* @param x
* the x coordinate of the point to check.
* @param y
* the y coordinate of the point to check.
* @return the point's location with respect to the rectangle.
*/
public abstract int outcode(double x, double y);
/**
* Creates an new rectangle that is the intersection of this rectangle with
* the given rectangle. The resulting rectangle may be empty. The data of
* this rectangle is left unchanged.
*
* @param r
* the rectangle to intersect with this rectangle.
* @return the new rectangle given by intersection.
*/
public abstract Rectangle2D createIntersection(Rectangle2D r);
/**
* Creates an new rectangle that is the union of this rectangle with the
* given rectangle. The new rectangle is the smallest rectangle which
* contains both this rectangle and the rectangle specified as a parameter.
* The data of this rectangle is left unchanged.
*
* @param r
* the rectangle to combine with this rectangle.
* @return the new rectangle given by union.
*/
public abstract Rectangle2D createUnion(Rectangle2D r);
/**
* Sets the data of this rectangle to match the data of the given rectangle.
*
* @param r
* the rectangle whose data is to be copied into this rectangle's
* fields.
*/
public void setRect(Rectangle2D r) {
setRect(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
@Override
public void setFrame(double x, double y, double width, double height) {
setRect(x, y, width, height);
}
public Rectangle2D getBounds2D() {
return (Rectangle2D)clone();
}
/**
* Determines whether any part of the line segment between (and including)
* the two given points touches any part of the rectangle, including its
* boundary.
*
* @param x1
* the x coordinate of one of the points that determines the line
* segment to test.
* @param y1
* the y coordinate of one of the points that determines the line
* segment to test.
* @param x2
* the x coordinate of one of the points that determines the line
* segment to test.
* @param y2
* the y coordinate of one of the points that determines the line
* segment to test.
* @return true, if at least one point of the line segment between the two
* points matches any point of the interior of the rectangle or the
* rectangle's boundary.
*/
public boolean intersectsLine(double x1, double y1, double x2, double y2) {
double rx1 = getX();
double ry1 = getY();
double rx2 = rx1 + getWidth();
double ry2 = ry1 + getHeight();
return (rx1 <= x1 && x1 <= rx2 && ry1 <= y1 && y1 <= ry2)
|| (rx1 <= x2 && x2 <= rx2 && ry1 <= y2 && y2 <= ry2)
|| Line2D.linesIntersect(rx1, ry1, rx2, ry2, x1, y1, x2, y2)
|| Line2D.linesIntersect(rx2, ry1, rx1, ry2, x1, y1, x2, y2);
}
/**
* Determines whether any part of the specified line segment touches any
* part of the rectangle, including its boundary.
*
* @param l
* the line segment to test.
* @return true, if at least one point of the given line segment matches any
* point of the interior of the rectangle or the rectangle's
* boundary.
*/
public boolean intersectsLine(Line2D l) {
return intersectsLine(l.getX1(), l.getY1(), l.getX2(), l.getY2());
}
/**
* Gets the location of the point with respect to the rectangle and packs
* the information into a single integer using the bitmasks
* {@link Rectangle2D#OUT_LEFT}, {@link Rectangle2D#OUT_RIGHT},
* {@link Rectangle2D#OUT_TOP}, and {@link Rectangle2D#OUT_BOTTOM}. If the
* rectangle has zero or negative width, then every point is regarded as
* being both to the left and to the right of the rectangle. Similarly, if
* the height is zero or negative then all points are considered to be both
* both above and below it.
*
* @param p
* the point to check.
* @return the point's location with respect to the rectangle.
*/
public int outcode(Point2D p) {
return outcode(p.getX(), p.getY());
}
public boolean contains(double x, double y) {
if (isEmpty()) {
return false;
}
double x1 = getX();
double y1 = getY();
double x2 = x1 + getWidth();
double y2 = y1 + getHeight();
return x1 <= x && x < x2 && y1 <= y && y < y2;
}
public boolean intersects(double x, double y, double width, double height) {
if (isEmpty() || width <= 0.0 || height <= 0.0) {
return false;
}
double x1 = getX();
double y1 = getY();
double x2 = x1 + getWidth();
double y2 = y1 + getHeight();
return x + width > x1 && x < x2 && y + height > y1 && y < y2;
}
public boolean contains(double x, double y, double width, double height) {
if (isEmpty() || width <= 0.0 || height <= 0.0) {
return false;
}
double x1 = getX();
double y1 = getY();
double x2 = x1 + getWidth();
double y2 = y1 + getHeight();
return x1 <= x && x + width <= x2 && y1 <= y && y + height <= y2;
}
/**
* Changes the data values of the destination rectangle to match the
* intersection of the two source rectangles, leaving the two source
* rectangles unchanged. The resulting rectangle may be empty.
*
* @param src1
* one of the two source rectangles giving the data to intersect.
* @param src2
* one of the two source rectangles giving the data to intersect.
* @param dst
* the destination object where the data of the intersection is
* written.
*/
public static void intersect(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
double x1 = Math.max(src1.getMinX(), src2.getMinX());
double y1 = Math.max(src1.getMinY(), src2.getMinY());
double x2 = Math.min(src1.getMaxX(), src2.getMaxX());
double y2 = Math.min(src1.getMaxY(), src2.getMaxY());
dst.setFrame(x1, y1, x2 - x1, y2 - y1);
}
/**
* Changes the data values of the destination rectangle to match the union
* of the two source rectangles, leaving the two source rectangles
* unchanged. The union is the smallest rectangle that completely covers the
* two source rectangles.
*
* @param src1
* one of the two source rectangles giving the data.
* @param src2
* one of the two source rectangles giving the data.
* @param dst
* the destination object where the data of the union is written.
*/
public static void union(Rectangle2D src1, Rectangle2D src2, Rectangle2D dst) {
double x1 = Math.min(src1.getMinX(), src2.getMinX());
double y1 = Math.min(src1.getMinY(), src2.getMinY());
double x2 = Math.max(src1.getMaxX(), src2.getMaxX());
double y2 = Math.max(src1.getMaxY(), src2.getMaxY());
dst.setFrame(x1, y1, x2 - x1, y2 - y1);
}
/**
* Enlarges the rectangle so that it includes the given point.
*
* @param x
* the x coordinate of the new point to be covered by the
* rectangle.
* @param y
* the y coordinate of the new point to be covered by the
* rectangle.
*/
public void add(double x, double y) {
double x1 = Math.min(getMinX(), x);
double y1 = Math.min(getMinY(), y);
double x2 = Math.max(getMaxX(), x);
double y2 = Math.max(getMaxY(), y);
setRect(x1, y1, x2 - x1, y2 - y1);
}
/**
* Enlarges the rectangle so that it includes the given point.
*
* @param p
* the new point to be covered by the rectangle.
*/
public void add(Point2D p) {
add(p.getX(), p.getY());
}
/**
* Enlarges the rectangle so that it covers the given rectangle.
*
* @param r
* the new rectangle to be covered by this rectangle.
*/
public void add(Rectangle2D r) {
union(this, r, this);
}
public PathIterator getPathIterator(AffineTransform t) {
return new Iterator(this, t);
}
@Override
public PathIterator getPathIterator(AffineTransform t, double flatness) {
return new Iterator(this, t);
}
@Override
public int hashCode() {
HashCode hash = new HashCode();
hash.append(getX());
hash.append(getY());
hash.append(getWidth());
hash.append(getHeight());
return hash.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Rectangle2D) {
Rectangle2D r = (Rectangle2D)obj;
return getX() == r.getX() && getY() == r.getY() && getWidth() == r.getWidth()
&& getHeight() == r.getHeight();
}
return false;
}
}
@@ -0,0 +1,297 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
import java.awt.Rectangle;
import java.awt.Shape;
/**
* The Class RectangularShape represents a Shape whose data is (at least
* partially) described by a rectangular frame. This includes shapes which are
* obviously rectangular (such as Rectangle2D) as well as shapes like Arc2D
* which are largely determined by the rectangle they fit inside.
*
* @since Android 1.0
*/
public abstract class RectangularShape implements Shape, Cloneable {
/**
* Instantiates a new rectangular shape.
*/
protected RectangularShape() {
}
/**
* Gets the x coordinate of the upper left corner of the rectangle.
*
* @return the x coordinate of the upper left corner of the rectangle.
*/
public abstract double getX();
/**
* Gets the y coordinate of the upper left corner of the rectangle.
*
* @return the y coordinate of the upper left corner of the rectangle.
*/
public abstract double getY();
/**
* Gets the width of the rectangle.
*
* @return the width of the rectangle.
*/
public abstract double getWidth();
/**
* Gets the height of the rectangle.
*
* @return the height of the rectangle.
*/
public abstract double getHeight();
/**
* Checks if this is an empty rectangle: one with zero as its width or
* height.
*
* @return true, if the width or height is empty.
*/
public abstract boolean isEmpty();
/**
* Sets the data for the bounding rectangle in terms of double values.
*
* @param x
* the x coordinate of the upper left corner of the rectangle.
* @param y
* the y coordinate of the upper left corner of the rectangle.
* @param w
* the width of the rectangle.
* @param h
* the height of the rectangle.
*/
public abstract void setFrame(double x, double y, double w, double h);
/**
* Gets the minimum x value of the bounding rectangle (the x coordinate of
* the upper left corner of the rectangle).
*
* @return the minimum x value of the bounding rectangle.
*/
public double getMinX() {
return getX();
}
/**
* Gets the minimum y value of the bounding rectangle (the y coordinate of
* the upper left corner of the rectangle).
*
* @return the minimum y value of the bounding rectangle.
*/
public double getMinY() {
return getY();
}
/**
* Gets the maximum x value of the bounding rectangle (the x coordinate of
* the upper left corner of the rectangle plus the rectangle's width).
*
* @return the maximum x value of the bounding rectangle.
*/
public double getMaxX() {
return getX() + getWidth();
}
/**
* Gets the maximum y value of the bounding rectangle (the y coordinate of
* the upper left corner of the rectangle plus the rectangle's height).
*
* @return the maximum y value of the bounding rectangle.
*/
public double getMaxY() {
return getY() + getHeight();
}
/**
* Gets the x coordinate of the center of the rectangle.
*
* @return the x coordinate of the center of the rectangle.
*/
public double getCenterX() {
return getX() + getWidth() / 2.0;
}
/**
* Gets the y coordinate of the center of the rectangle.
*
* @return the y coordinate of the center of the rectangle.
*/
public double getCenterY() {
return getY() + getHeight() / 2.0;
}
/**
* Places the rectangle's size and location data in a new Rectangle2D object
* and returns it.
*
* @return the bounding rectangle as a new Rectangle2D object.
*/
public Rectangle2D getFrame() {
return new Rectangle2D.Double(getX(), getY(), getWidth(), getHeight());
}
/**
* Sets the bounding rectangle in terms of a Point2D which gives its upper
* left corner and a Dimension2D object giving its width and height.
*
* @param loc
* the new upper left corner coordinate.
* @param size
* the new size dimensions.
*/
public void setFrame(Point2D loc, Dimension2D size) {
setFrame(loc.getX(), loc.getY(), size.getWidth(), size.getHeight());
}
/**
* Sets the bounding rectangle to match the data contained in the specified
* Rectangle2D.
*
* @param r
* the rectangle that gives the new frame data.
*/
public void setFrame(Rectangle2D r) {
setFrame(r.getX(), r.getY(), r.getWidth(), r.getHeight());
}
/**
* Sets the framing rectangle given two opposite corners. Any two corners
* may be used in any order as long as they are diagonally opposite one
* another.
*
* @param x1
* the x coordinate of one of the corner points.
* @param y1
* the y coordinate of one of the corner points.
* @param x2
* the x coordinate of the other corner point.
* @param y2
* the y coordinate of the other corner point.
*/
public void setFrameFromDiagonal(double x1, double y1, double x2, double y2) {
double rx, ry, rw, rh;
if (x1 < x2) {
rx = x1;
rw = x2 - x1;
} else {
rx = x2;
rw = x1 - x2;
}
if (y1 < y2) {
ry = y1;
rh = y2 - y1;
} else {
ry = y2;
rh = y1 - y2;
}
setFrame(rx, ry, rw, rh);
}
/**
* Sets the framing rectangle given two opposite corners. Any two corners
* may be used in any order as long as they are diagonally opposite one
* another.
*
* @param p1
* one of the corner points.
* @param p2
* the other corner point.
*/
public void setFrameFromDiagonal(Point2D p1, Point2D p2) {
setFrameFromDiagonal(p1.getX(), p1.getY(), p2.getX(), p2.getY());
}
/**
* Sets the framing rectangle given the center point and one corner. Any
* corner may be used.
*
* @param centerX
* the x coordinate of the center point.
* @param centerY
* the y coordinate of the center point.
* @param cornerX
* the x coordinate of one of the corner points.
* @param cornerY
* the y coordinate of one of the corner points.
*/
public void setFrameFromCenter(double centerX, double centerY, double cornerX, double cornerY) {
double width = Math.abs(cornerX - centerX);
double height = Math.abs(cornerY - centerY);
setFrame(centerX - width, centerY - height, width * 2.0, height * 2.0);
}
/**
* Sets the framing rectangle given the center point and one corner. Any
* corner may be used.
*
* @param center
* the center point.
* @param corner
* a corner point.
*/
public void setFrameFromCenter(Point2D center, Point2D corner) {
setFrameFromCenter(center.getX(), center.getY(), corner.getX(), corner.getY());
}
public boolean contains(Point2D point) {
return contains(point.getX(), point.getY());
}
public boolean intersects(Rectangle2D rect) {
return intersects(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
}
public boolean contains(Rectangle2D rect) {
return contains(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
}
public Rectangle getBounds() {
int x1 = (int)Math.floor(getMinX());
int y1 = (int)Math.floor(getMinY());
int x2 = (int)Math.ceil(getMaxX());
int y2 = (int)Math.ceil(getMaxY());
return new Rectangle(x1, y1, x2 - x1, y2 - y1);
}
public PathIterator getPathIterator(AffineTransform t, double flatness) {
return new FlatteningPathIterator(getPathIterator(t), flatness);
}
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError();
}
}
}
@@ -0,0 +1,635 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Denis M. Kishenko
* @version $Revision$
*/
package java.awt.geom;
import java.util.NoSuchElementException;
import org.apache.harmony.awt.internal.nls.Messages;
/**
* The Class RoundRectangle2D describes a rectangle with rounded corners with
* high-precision data that is appropriate for geometric operations.
*
* @since Android 1.0
*/
public abstract class RoundRectangle2D extends RectangularShape {
/**
* The Class Float is the subclass of RoundRectangle2D that has all of its
* data values stored with float-level precision.
*
* @since Android 1.0
*/
public static class Float extends RoundRectangle2D {
/**
* The x coordinate of the rectangle's upper left corner.
*/
public float x;
/**
* The y coordinate of the rectangle's upper left corner.
*/
public float y;
/**
* The width of the rectangle.
*/
public float width;
/**
* The height of the rectangle.
*/
public float height;
/**
* The arc width of the rounded corners.
*/
public float arcwidth;
/**
* The arc height of the rounded corners.
*/
public float archeight;
/**
* Instantiates a new float-valued RoundRectangle2D with its data-values
* set to zero.
*/
public Float() {
}
/**
* Instantiates a new float-valued RoundRectangle2D with the specified
* data values.
*
* @param x
* the x coordinate of the rectangle's upper left corner.
* @param y
* the y coordinate of the rectangle's upper left corner.
* @param width
* the width of the rectangle.
* @param height
* the height of the rectangle.
* @param arcwidth
* the arc width of the rounded corners.
* @param archeight
* the arc height of the rounded corners.
*/
public Float(float x, float y, float width, float height, float arcwidth, float archeight) {
setRoundRect(x, y, width, height, arcwidth, archeight);
}
@Override
public double getX() {
return x;
}
@Override
public double getY() {
return y;
}
@Override
public double getWidth() {
return width;
}
@Override
public double getHeight() {
return height;
}
@Override
public double getArcWidth() {
return arcwidth;
}
@Override
public double getArcHeight() {
return archeight;
}
@Override
public boolean isEmpty() {
return width <= 0.0f || height <= 0.0f;
}
/**
* Sets the data of the round rectangle.
*
* @param x
* the x coordinate of the rectangle's upper left corner.
* @param y
* the y coordinate of the rectangle's upper left corner.
* @param width
* the width of the rectangle.
* @param height
* the height of the rectangle.
* @param arcwidth
* the arc width of the rounded corners.
* @param archeight
* the arc height of the rounded corners.
*/
public void setRoundRect(float x, float y, float width, float height, float arcwidth,
float archeight) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.arcwidth = arcwidth;
this.archeight = archeight;
}
@Override
public void setRoundRect(double x, double y, double width, double height, double arcwidth,
double archeight) {
this.x = (float)x;
this.y = (float)y;
this.width = (float)width;
this.height = (float)height;
this.arcwidth = (float)arcwidth;
this.archeight = (float)archeight;
}
@Override
public void setRoundRect(RoundRectangle2D rr) {
this.x = (float)rr.getX();
this.y = (float)rr.getY();
this.width = (float)rr.getWidth();
this.height = (float)rr.getHeight();
this.arcwidth = (float)rr.getArcWidth();
this.archeight = (float)rr.getArcHeight();
}
public Rectangle2D getBounds2D() {
return new Rectangle2D.Float(x, y, width, height);
}
}
/**
* The Class Double is the subclass of RoundRectangle2D that has all of its
* data values stored with double-level precision.
*
* @since Android 1.0
*/
public static class Double extends RoundRectangle2D {
/**
* The x coordinate of the rectangle's upper left corner.
*/
public double x;
/**
* The y coordinate of the rectangle's upper left corner.
*/
public double y;
/**
* The width of the rectangle.
*/
public double width;
/**
* The height of the rectangle.
*/
public double height;
/**
* The arc width of the rounded corners.
*/
public double arcwidth;
/**
* The arc height of the rounded corners.
*/
public double archeight;
/**
* Instantiates a new double-valued RoundRectangle2D with its
* data-values set to zero.
*/
public Double() {
}
/**
* Instantiates a new double-valued RoundRectangle2D with the specified
* data values.
*
* @param x
* the x coordinate of the rectangle's upper left corner.
* @param y
* the y coordinate of the rectangle's upper left corner.
* @param width
* the width of the rectangle.
* @param height
* the height of the rectangle.
* @param arcwidth
* the arc width of the rounded corners.
* @param archeight
* the arc height of the rounded corners.
*/
public Double(double x, double y, double width, double height, double arcwidth,
double archeight) {
setRoundRect(x, y, width, height, arcwidth, archeight);
}
@Override
public double getX() {
return x;
}
@Override
public double getY() {
return y;
}
@Override
public double getWidth() {
return width;
}
@Override
public double getHeight() {
return height;
}
@Override
public double getArcWidth() {
return arcwidth;
}
@Override
public double getArcHeight() {
return archeight;
}
@Override
public boolean isEmpty() {
return width <= 0.0 || height <= 0.0;
}
@Override
public void setRoundRect(double x, double y, double width, double height, double arcwidth,
double archeight) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.arcwidth = arcwidth;
this.archeight = archeight;
}
@Override
public void setRoundRect(RoundRectangle2D rr) {
this.x = rr.getX();
this.y = rr.getY();
this.width = rr.getWidth();
this.height = rr.getHeight();
this.arcwidth = rr.getArcWidth();
this.archeight = rr.getArcHeight();
}
public Rectangle2D getBounds2D() {
return new Rectangle2D.Double(x, y, width, height);
}
}
/*
* RoundRectangle2D path iterator
*/
/**
* The subclass of PathIterator to traverse a RoundRectangle2D.
*/
class Iterator implements PathIterator {
/*
* Path for round corners generated the same way as Ellipse2D
*/
/**
* The coefficient to calculate control points of Bezier curves.
*/
double u = 0.5 - 2.0 / 3.0 * (Math.sqrt(2.0) - 1.0);
/**
* The points coordinates calculation table.
*/
double points[][] = {
{
0.0, 0.5, 0.0, 0.0
}, // MOVETO
{
1.0, -0.5, 0.0, 0.0
}, // LINETO
{
1.0, -u, 0.0, 0.0, // CUBICTO
1.0, 0.0, 0.0, u, 1.0, 0.0, 0.0, 0.5
}, {
1.0, 0.0, 1.0, -0.5
}, // LINETO
{
1.0, 0.0, 1.0, -u, // CUBICTO
1.0, -u, 1.0, 0.0, 1.0, -0.5, 1.0, 0.0
}, {
0.0, 0.5, 1.0, 0.0
}, // LINETO
{
0.0, u, 1.0, 0.0, // CUBICTO
0.0, 0.0, 1.0, -u, 0.0, 0.0, 1.0, -0.5
}, {
0.0, 0.0, 0.0, 0.5
}, // LINETO
{
0.0, 0.0, 0.0, u, // CUBICTO
0.0, u, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0
}
};
/**
* The segment types correspond to points array.
*/
int types[] = {
SEG_MOVETO, SEG_LINETO, SEG_CUBICTO, SEG_LINETO, SEG_CUBICTO, SEG_LINETO,
SEG_CUBICTO, SEG_LINETO, SEG_CUBICTO
};
/**
* The x coordinate of left-upper corner of the round rectangle bounds.
*/
double x;
/**
* The y coordinate of left-upper corner of the round rectangle bounds.
*/
double y;
/**
* The width of the round rectangle bounds.
*/
double width;
/**
* The height of the round rectangle bounds.
*/
double height;
/**
* The width of arc corners of the round rectangle.
*/
double aw;
/**
* The height of arc corners of the round rectangle.
*/
double ah;
/**
* The path iterator transformation.
*/
AffineTransform t;
/**
* The current segment index.
*/
int index;
/**
* Constructs a new RoundRectangle2D.Iterator for given round rectangle
* and transformation.
*
* @param rr
* - the source RoundRectangle2D object
* @param at
* - the AffineTransform object to apply rectangle path
*/
Iterator(RoundRectangle2D rr, AffineTransform at) {
this.x = rr.getX();
this.y = rr.getY();
this.width = rr.getWidth();
this.height = rr.getHeight();
this.aw = Math.min(width, rr.getArcWidth());
this.ah = Math.min(height, rr.getArcHeight());
this.t = at;
if (width < 0.0 || height < 0.0 || aw < 0.0 || ah < 0.0) {
index = points.length;
}
}
public int getWindingRule() {
return WIND_NON_ZERO;
}
public boolean isDone() {
return index > points.length;
}
public void next() {
index++;
}
public int currentSegment(double[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
if (index == points.length) {
return SEG_CLOSE;
}
int j = 0;
double p[] = points[index];
for (int i = 0; i < p.length; i += 4) {
coords[j++] = x + p[i + 0] * width + p[i + 1] * aw;
coords[j++] = y + p[i + 2] * height + p[i + 3] * ah;
}
if (t != null) {
t.transform(coords, 0, coords, 0, j / 2);
}
return types[index];
}
public int currentSegment(float[] coords) {
if (isDone()) {
// awt.4B=Iterator out of bounds
throw new NoSuchElementException(Messages.getString("awt.4B")); //$NON-NLS-1$
}
if (index == points.length) {
return SEG_CLOSE;
}
int j = 0;
double p[] = points[index];
for (int i = 0; i < p.length; i += 4) {
coords[j++] = (float)(x + p[i + 0] * width + p[i + 1] * aw);
coords[j++] = (float)(y + p[i + 2] * height + p[i + 3] * ah);
}
if (t != null) {
t.transform(coords, 0, coords, 0, j / 2);
}
return types[index];
}
}
/**
* Instantiates a new RoundRectangle2D.
*/
protected RoundRectangle2D() {
}
/**
* Gets the arc width.
*
* @return the arc width.
*/
public abstract double getArcWidth();
/**
* Gets the arc height.
*
* @return the arc height.
*/
public abstract double getArcHeight();
/**
* Sets the data of the RoundRectangle2D.
*
* @param x
* the x coordinate of the rectangle's upper left corner.
* @param y
* the y coordinate of the rectangle's upper left corner.
* @param width
* the width of the rectangle.
* @param height
* the height of the rectangle.
* @param arcWidth
* the arc width of the rounded corners.
* @param arcHeight
* the arc height of the rounded corners.
*/
public abstract void setRoundRect(double x, double y, double width, double height,
double arcWidth, double arcHeight);
/**
* Sets the data of the RoundRectangle2D by copying the values from an
* existing RoundRectangle2D.
*
* @param rr
* the round rectangle to copy the data from.
* @throws NullPointerException
* if rr is null.
*/
public void setRoundRect(RoundRectangle2D rr) {
setRoundRect(rr.getX(), rr.getY(), rr.getWidth(), rr.getHeight(), rr.getArcWidth(), rr
.getArcHeight());
}
@Override
public void setFrame(double x, double y, double width, double height) {
setRoundRect(x, y, width, height, getArcWidth(), getArcHeight());
}
public boolean contains(double px, double py) {
if (isEmpty()) {
return false;
}
double rx1 = getX();
double ry1 = getY();
double rx2 = rx1 + getWidth();
double ry2 = ry1 + getHeight();
if (px < rx1 || px >= rx2 || py < ry1 || py >= ry2) {
return false;
}
double aw = getArcWidth() / 2.0;
double ah = getArcHeight() / 2.0;
double cx, cy;
if (px < rx1 + aw) {
cx = rx1 + aw;
} else if (px > rx2 - aw) {
cx = rx2 - aw;
} else {
return true;
}
if (py < ry1 + ah) {
cy = ry1 + ah;
} else if (py > ry2 - ah) {
cy = ry2 - ah;
} else {
return true;
}
px = (px - cx) / aw;
py = (py - cy) / ah;
return px * px + py * py <= 1.0;
}
public boolean intersects(double rx, double ry, double rw, double rh) {
if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
return false;
}
double x1 = getX();
double y1 = getY();
double x2 = x1 + getWidth();
double y2 = y1 + getHeight();
double rx1 = rx;
double ry1 = ry;
double rx2 = rx + rw;
double ry2 = ry + rh;
if (rx2 < x1 || x2 < rx1 || ry2 < y1 || y2 < ry1) {
return false;
}
double cx = (x1 + x2) / 2.0;
double cy = (y1 + y2) / 2.0;
double nx = cx < rx1 ? rx1 : (cx > rx2 ? rx2 : cx);
double ny = cy < ry1 ? ry1 : (cy > ry2 ? ry2 : cy);
return contains(nx, ny);
}
public boolean contains(double rx, double ry, double rw, double rh) {
if (isEmpty() || rw <= 0.0 || rh <= 0.0) {
return false;
}
double rx1 = rx;
double ry1 = ry;
double rx2 = rx + rw;
double ry2 = ry + rh;
return contains(rx1, ry1) && contains(rx2, ry1) && contains(rx2, ry2) && contains(rx1, ry2);
}
public PathIterator getPathIterator(AffineTransform at) {
return new Iterator(this, at);
}
}
@@ -0,0 +1,8 @@
<html>
<body>
<p>
This package contains classes and interfaces related to Java2D shapes and geometry.
</p>
@since Android 1.0
</body>
</html>
@@ -0,0 +1,88 @@
package java.awt.image;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
public class BufferedImage extends Image implements RenderedImage {
public static final int TYPE_INT_ARGB = 2;
private Bitmap bitmap;
private WritableRaster raster;
private Bitmap mkBitmap(int width, int height, Config mode) {
return Bitmap.createBitmap(width, height, mode);
}
public BufferedImage(Bitmap bitmap) {
if (bitmap != null) {
this.bitmap = bitmap;
} else {
mkBitmap(1, 1, Config.ARGB_8888);
}
init();
}
public BufferedImage(int width, int height, int imageType) {
this.bitmap = mkBitmap(width, height, Config.ARGB_8888);
/*
if (imageType == TYPE_INT_ARGB) {
this.bitmap = mkBitmap(width, height, Config.ARGB_8888);
} else {
this.bitmap = mkBitmap(width, height, Config.HARDWARE);
}
*/
init();
}
public void init() {
raster = new WritableRaster(this);
}
public int getWidth() {
return this.bitmap.getWidth();
}
public int getHeight() {
return this.bitmap.getHeight();
}
public int[] getRGB(int x, int y, int w, int h, int[] rgbArray, int offset, int scansize) {
if (rgbArray == null) {
rgbArray = new int[((scansize * h) + offset)];
}
this.bitmap.getPixels(rgbArray, offset, scansize, x, y, w, h);
return rgbArray;
}
public Graphics getGraphics() {
return new Graphics2D(this);
}
public Graphics2D createGraphics() {
return new Graphics2D(this);
}
public void setRGB(int x, int y, int w, int h, int[] rgbArray, int offset, int scansize) {
System.out.println("Setting RGB stub");
if (rgbArray == null) {
int size = (h - 1) * scansize + w;
rgbArray = new int[size];
}
bitmap.setPixels(rgbArray, offset, scansize, x, y, w, h);
}
public WritableRaster getRaster() {
return raster;
}
public Bitmap getAndroidBitmap() {
return this.bitmap;
}
public int getType() {
return TYPE_INT_ARGB;
}
}
@@ -0,0 +1,12 @@
package java.awt.image;
public class DataBuffer {
public static final int TYPE_BYTE = 0;
public static final int TYPE_DOUBLE = 5;
public static final int TYPE_FLOAT = 4;
public static final int TYPE_INT = 3;
public static final int TYPE_SHORT = 2;
public static final int TYPE_UNDEFINED = 32;
public static final int TYPE_USHORT = 1;
}
@@ -0,0 +1,14 @@
package java.awt.image;
public class DataBufferInt extends DataBuffer {
private int[] array;
public DataBufferInt(int[] array, int size) {
this.array = array;
}
public int[] getData() {
return this.array;
}
}
@@ -0,0 +1,5 @@
package java.awt.image;
public class ImageObserver
{
}
@@ -0,0 +1,5 @@
package java.awt.image;
public interface RenderedImage
{
}
@@ -0,0 +1,16 @@
package java.awt.image;
public class WritableRaster {
private BufferedImage image;
public WritableRaster(BufferedImage image) {
this.image = image;
}
public DataBuffer getDataBuffer() {
int[] theBuf = new int[(this.image.getWidth() * this.image.getHeight())];
this.image.getRGB(0, 0, this.image.getWidth(), this.image.getHeight(), theBuf, 0, this.image.getWidth());
return new DataBufferInt(theBuf, theBuf.length);
}
}
@@ -0,0 +1,53 @@
package java.awt.mod;
import android.graphics.*;
import android.util.*;
import java.awt.image.*;
import java.lang.reflect.*;
import java.util.*;
import net.kdt.pojavlaunch.*;
public class ModdingKit
{
public static MainActivity getCurrentActivity()
{
try {
Class activityThreadClass = Class.forName("android.app.ActivityThread");
Object activityThread = activityThreadClass.getMethod("currentActivityThread").invoke(null);
Field activitiesField = activityThreadClass.getDeclaredField("mActivities");
activitiesField.setAccessible(true);
Map<Object, Object> activities = (Map<Object, Object>) activitiesField.get(activityThread);
if (activities == null) return null;
for (Object activityRecord : activities.values()) {
Class activityRecordClass = activityRecord.getClass();
Field pausedField = activityRecordClass.getDeclaredField("paused");
pausedField.setAccessible(true);
if (!pausedField.getBoolean(activityRecord)) {
Field activityField = activityRecordClass.getDeclaredField("activity");
activityField.setAccessible(true);
MainActivity activity = (MainActivity) activityField.get(activityRecord);
return activity;
}
}
return null;
} catch (Throwable th) {
return null;
}
}
public static Bitmap bufferToBitmap(BufferedImage bufferedImage) {
BufferedImage bufferedImage2 = bufferedImage;
return pixelsToBitmap(((DataBufferInt) bufferedImage2.getRaster().getDataBuffer()).getData(), bufferedImage2.getWidth(), bufferedImage2.getHeight());
}
public static Bitmap pixelsToBitmap(int[] iArr, int i, int i2) {
int[] iArr2 = iArr;
int i3 = i;
int i4 = i2;
Bitmap createBitmap = Bitmap.createBitmap(i3, i4, Bitmap.Config.RGB_565);
createBitmap.setPixels(iArr2, 0, i3, 0, 0, i3, i4);
return createBitmap;
}
}
Loaded 100 of 2887 files, more files were not shown because too many files have changed in this diff. Show more